2

次のコードは、車両名を含むテーブルと地域名を含むテーブルを取得し、それらを結果テーブルに結合します。次に、結果テーブルでCOUNTを実行して、地域ごとに何台の車両があるかを示します。

すべての地域とすべての車両を強制的にカウントアップするようにコードを修正する必要があります。現在、COUNTステートメントには車両を含まない地域は表示されません(これを表示するために、結果からいくつかのエントリを手動で削除しました)。誰かがこれを行う簡単な方法を説明できますか?私はSQL2012を使用しており、簡単な解決策があることを望んでいます...

ここに画像の説明を入力してください

質問に答えるために、2つの元のテーブルにアクセスできなくなったと想定してください。現在、@tbl_resultsのみを使用しています。ありがとうございました。

注:これは車両と地域のテーブルから直接実行できることはわかっていますが、実際の作業では、他のプロセスの結果のテーブル変数を使用する必要があります。

DECLARE @tbl_vehicles TABLE (vehicleID int, vehicleName nvarchar(100))
DECLARE @tbl_regions TABLE (regionID int, regionName nvarchar(100))
DECLARE @tbl_results TABLE (regionID int, regionName nvarchar(100), vehicleID int, vehicleName nvarchar(100))

INSERT INTO @tbl_regions (regionID, regionName) VALUES (1, 'England')
INSERT INTO @tbl_regions (regionID, regionName) VALUES (2, 'United States')
INSERT INTO @tbl_regions (regionID, regionName) VALUES (3, 'Arctic')

INSERT INTO @tbl_vehicles (vehicleID, vehicleName) VALUES (1, 'Planes')
INSERT INTO @tbl_vehicles (vehicleID, vehicleName) VALUES (2, 'Trains')
INSERT INTO @tbl_vehicles (vehicleID, vehicleName) VALUES (3, 'Automobiles')

DECLARE @i INT
SET @i = 0 

WHILE @i < 100
    BEGIN
        INSERT INTO @tbl_results
            (regionID, regionName, vehicleID, vehicleName) 
        SELECT
            r.regionID, r.regionName, v.vehicleID, v.vehicleName 
        FROM
            @tbl_regions r CROSS JOIN
            @tbl_vehicles v 
        WHERE
            (r.regionID = CAST(RAND() * 4 AS INT)) AND
            (v.vehicleID = CAST(RAND() * 4 AS INT)) 
        SET @i = @i + 1
    END

-- remove trains in the arctic for count example
DELETE FROM @tbl_results WHERE (regionID=3) AND (vehicleID=2)

-- this statement needs to include ALL vehicles and ALL regions (even if no vehicles are found at a region)
SELECT 
    regionName,
    vehicleName,
    COUNT(*) as VehicleCount
FROM
    @tbl_results 
GROUP BY
    regionID,
    regionName,
    vehicleID,
    vehicleName
ORDER BY regionName, vehicleName  
4

4 に答える 4

2
SELECT  r.regionName
,       v.vehicleName
,       COUNT(res.vehicleName) as VehicleCount
FROM    (
        select  distinct regionName
        from    @tbl_results
        ) r
CROSS JOIN 
        (
        select  distinct vehicleName
        from    @tbl_results
        ) v
LEFT OUTER JOIN
        @tbl_results res
ON      r.regionName = res.regionName
        AND v.vehicleName = res.vehicleName
GROUP BY
        r.regionName
,       v.vehicleName
ORDER BY
        r.regionName
,       v.vehicleName
于 2013-02-01T12:46:33.357 に答える
1

私はそれをこのようにします:

WITH VehicleRegions AS
(
  SELECT
    *
  FROM
    tbl_vehicles,
    tbl_regions
 )
SELECT 
  VehicleRegions.VehicleName,
  VehicleRegions.RegionName,
  COUNT(tbl_results.regionID)
FROM
  VehicleRegions
  LEFT JOIN tbl_results ON VehicleRegions.VehicleID = tbl_results.VehicleID AND VehicleRegions.RegionID = tbl_results.RegionID
GROUP BY
  VehicleRegions.VehicleName,
  VehicleRegions.RegionName

フィドルを参照してください

フィドルでは、テーブル変数ではなくテーブルを使用しましたが、アイデアは有効です。すべての車両と地域のペアを含む共通テーブル式を作成します。次に、Count(results。[AnyColumn])を実行します。Count(*)を実行すると、結果のNULL値がカウントされます。あなたはそれを望まない。結果に値が含まれている場所のみをカウントする必要があります。

于 2013-02-01T13:18:16.817 に答える
1

これを試して:

DECLARE @tbl_vehicles TABLE (vehicleID int, vehicleName nvarchar(100))
DECLARE @tbl_regions TABLE (regionID int, regionName nvarchar(100))
DECLARE @tbl_results TABLE (regionID int, regionName nvarchar(100), 
                            vehicleID int, vehicleName nvarchar(100))

INSERT INTO @tbl_regions (regionID, regionName) VALUES (1, 'England')
INSERT INTO @tbl_regions (regionID, regionName) VALUES (2, 'United States')
INSERT INTO @tbl_regions (regionID, regionName) VALUES (3, 'Arctic')

INSERT INTO @tbl_vehicles (vehicleID, vehicleName) VALUES (1, 'Planes')
INSERT INTO @tbl_vehicles (vehicleID, vehicleName) VALUES (2, 'Trains')
INSERT INTO @tbl_vehicles (vehicleID, vehicleName) VALUES (3, 'Automobiles')

DECLARE @i INT
SET @i = 0 

WHILE @i < 100
    BEGIN
        INSERT INTO @tbl_results
            (regionID, regionName, vehicleID, vehicleName) 
        SELECT
            r.regionID, r.regionName, v.vehicleID, v.vehicleName 
        FROM
            @tbl_regions r CROSS JOIN
            @tbl_vehicles v 
        WHERE
            (r.regionID = CAST(RAND() * 4 AS INT)) AND
            (v.vehicleID = CAST(RAND() * 4 AS INT)) 
        SET @i = @i + 1
    END

-- remove trains in the arctic for count example
DELETE FROM @tbl_results WHERE (regionID=3) AND (vehicleID=2)

-- this statement needs to include ALL vehicles 
-- and ALL regions (even if no vehicles are found at a region)
SELECT 
    R.regionName,
    VE.vehicleName,
    ISNULL(COUNT(RES.regionID),0) as VehicleCount
FROM @tbl_regions R
CROSS JOIN @tbl_vehicles VE
LEFT JOIN @tbl_results RES
    ON R.regionID = RES.regionID AND VE.vehicleID = RES.vehicleID
GROUP BY
     R.regionName,
    VE.vehicleName
ORDER BY R.regionName, VE.vehicleName  
于 2013-02-01T12:47:52.623 に答える
0

左結合とisNullの組み合わせで目標を達成できます。一般的な考え方は次のようになります。

select f1, f2, isNull(count(*), 0) records
from t1 left join t2 on something
where whatever
group by f1, f2

詳細を追加できます。

于 2013-02-01T13:13:53.970 に答える