0

SQL クエリを機能させるのに苦労しています。IN FAILS で行が見つからない場合、写真のような行を返したいのですが、ifuserholdscertificate を「NO」に設定したいと考えています。

SELECT tuc.id,
       tu.firstName,
       tuc.uid,
       tuc.value,
       tc.name,
       count(tuc.value) over (PARTITION BY tuc.uid) AS 'amount',
       'certificate DESIRABLE' AS 'typeofthing' ,
       'YES' AS 'HasorNot',
       ifuserholdscertificate = CASE
                                    WHEN count(tuc.value) = 0 THEN 'NO'
                                    ELSE 'YES'
                                END
FROM t_user_certificates tuc,
     t_certificates tc,
     t_users tu
WHERE tuc.value IN (4,
                    12,
                    31)
  AND tuc.value = tc.id
  AND tu.id = tuc.uid
GROUP BY tuc.id,
         tu.firstName,
         tuc.uid,
         tuc.value,
         tc.name

これは、クエリが生成するデータです!

ここに画像の説明を入力 ご覧のように、一部の人が金額の行で 2 しか得られない場合でも、行をフェッチせず、ifuserholdscertificate を「NO」に設定します。

リクエストごとに更新!

select  tuc.id,
count(tuc.value) as 'counten',
tu.firstName,
tuc.uid,
tuc.value, 
tc.name, 
count(tuc.value) over (PARTITION BY tuc.uid) as 'amount',
'certificateDESIRABLE'  as 'typeofthing' ,
'YES' as 'HasorNot',
HasOrders = CASE
                WHEN count(tuc.value) = 0 THEN 'NO'
                ELSE 'YES'
            END
from t_user_certificates tuc                   
left outer join t_certificates tc
on tuc.value = tc.id
left outer join t_users tu
on tu.id = tuc.uid
GROUP BY tuc.id, tu.firstName, tuc.uid, tuc.value, tc.name

ここに画像の説明を入力

カウントには常に 1 があり、常に 'YES' です。

4

3 に答える 3

1

デバッグするクエリに列を追加します。そして、それらの結果をスクリーン ショットで示します。

MyCOUNT = count(tuc.value),

私のノースウィンドの例は問題なく動作します。親 Customer の Orders (行) がない場合、「いいえ」が返されます。

...............

Use Northwind
GO

Select 
    custs.CustomerID,
    MyCOUNT = count(ords.OrderID),
    HasOrders = CASE
        WHEN count(ords.OrderID) = 0 THEN 'NO'
        ELSE 'YES'
    END
from 
    [dbo].[Customers] custs left outer join [dbo].[Orders] ords on custs.CustomerID = ords.CustomerID
GROUP BY 
    custs.CustomerID
order by 2

何が起こっているかを示す追加のクエリを次に示します。

Select Label = 'You get no results here', custs.CustomerID , ords.OrderID 
from 
    [dbo].[Customers] custs join [dbo].[Orders] ords on custs.CustomerID = ords.CustomerID
Where
    ords.OrderID IS NULL


Select Label = 'You get Customers with no Orders here', custs.CustomerID , ords.OrderID 
from 
    [dbo].[Customers] custs left outer join [dbo].[Orders] ords on custs.CustomerID = ords.CustomerID
Where
    ords.OrderID IS NULL


Select Label = 'You get Customers with or without Orders here', custs.CustomerID , ords.OrderID 
from 
    [dbo].[Customers] custs left outer join [dbo].[Orders] ords on custs.CustomerID = ords.CustomerID

pubs と Northwind データベースは、ここから入手できます。ほとんどの開発者は、このような状況を解決するためにこれらのデータベース (および AdventureWorks) を既にインストールしているため、これは役に立ちます。

http://msdn.microsoft.com/en-us/library/ms143221(v=sql.105).aspx

于 2013-03-18T22:51:14.313 に答える
1

これは、あなたが探しているものにもっと似ているかもしれません。where句にINビットがあるため、常に1を返し、証明書のないユーザーはいません。したがって、外部結合を使用しても、これらの値を持つ t_user_certificates からの行のみが返されます。これは実質的に内部結合になります。ANSI 結合構文はあなたの友達です。JOIN ロジックをフィルターから分離します。

SELECT tuc.id,
       tu.firstName,
       tuc.uid,
       tuc.value,
       tc.name,
       count(tuc.value) AS 'amount',
       'certificate DESIRABLE' AS 'typeofthing' ,
       'YES' AS 'HasorNot',
       ifuserholdscertificate = CASE
                                    WHEN count(tuc.value) > 0 THEN 'YES'
                                    ELSE 'NO'
                                END
FROM
    t_users tu
LEFT JOIN t_user_certificates tuc
    ON
    tu.id = tuc.uid
    AND 
    tuc.value IN
    (
        4
        , 12
        , 31
    )
LEFT JOIN
     t_certificates tc
    ON
    tuc.value = tc.id

GROUP BY tuc.id,
         tu.firstName,
         tuc.uid,
         tuc.value,
         tc.name;
于 2013-03-19T15:23:14.787 に答える
1

説明していないゼロの代わりにヌルを取得している可能性があります。代わりにこれを試します:

ifuserholdscertificate = CASE                                  
    WHEN (count(tuc.value) = 0 or count(tuc.Value) = null) THEN 'NO'
    ELSE 'YES'
    END

人々が2を得ると述べているのに、ゼロを考慮して「いいえ」の答えを期待している理由がわかりません。収集しているソース データの感覚がなければ、データを参照する前にデータがどのように見えるかを知ることは困難です。ウィンドウ関数 ( over(partion by..) ) も使用しており、通常のカウント関数とは異なるデータが得られます。ウィンドウ関数で case when 式を使用することが目標の場合は、入れ子になった select または cte を実行して最初に数値を取得し、後でそれらに対してロジックを実行する必要があります。

このようなもの:

declare @Person Table ( personID int identity, person varchar(8));

insert into @Person values ('Brett'),('Sean'),('Chad');

declare @Orders table ( OrderID int identity, PersonID int, Desciption varchar(32), Amount int);

insert into @Orders values (1, 'Shirt', 20),(2, 'Shirt', 22),(2, 'Shoes', 52);

With a as 
    (
    Select 
        p.person
    ,   count(o.orderID) over(partition by person) as Count
    from @Person p
        left join @Orders o on p.personID = o.PersonID
    )
select
    person
,   case when Count = 0 then 'No' else cast(Count as varchar(8)) end as Count
from a
于 2013-03-18T22:28:50.450 に答える