以下代码采用包含车辆名称的表格和包含区域名称的表格,并将它们组合到结果表中。 然后,我在结果表上执行COUNT,以显示每个地区有多少辆车。
我需要修改代码以强制所有区域和所有车辆计算在内。目前COUNT语句不显示任何不包含车辆的区域(我已手动删除结果中的一些条目以显示此信息)。谁能说明一个快速的方法来做到这一点?我正在使用SQL 2012,希望有一个简单的解决方案......
为了回答这个问题,请假设不再可以访问这两个原始表,我们现在只使用@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
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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
请参阅Fiddle
在小提琴中,我使用的是表格而不是表格变量,但这个想法是有效的。创建包含所有车辆和区域对的公用表表达式。然后做一个Count(结果。[AnyColumn])。如果执行Count(*),则计算结果中的NULL值。你不希望这样。您只想计算结果包含值的位置。
答案 3 :(得分:0)
您可以结合使用left join和isNull来实现目标。总体思路如下:
select f1, f2, isNull(count(*), 0) records
from t1 left join t2 on something
where whatever
group by f1, f2
您可以添加详细信息。