在回答这些类型的问题时,我喜欢在 tempdb 中创建一个示例表。
--
-- Create test table
--
-- Just toss away code
USE tempdb;
GO
-- Create a simple table
CREATE TABLE my_orders
(
my_orderstatus_id int,
my_orderstage_id int
);
GO
如果您还没有查看 Jeff Moden 的计数表,那么您应该查看。它们是一种以关系代数方式进行循环的快速方法。我正在加载组合 (1..5)(1..5) 次和 (6..10)(6..10) 两次。 go 后面的数字表示运行 TSQL 的次数。
--
-- Load test table
--
-- Create some data (1-5) x 4 counts
;
WITH cteTally1 (my_number1) AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY a.name) AS my_number
FROM
sys.objects a
CROSS JOIN
sys.objects b
),
cteTally2 (my_number2) AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY a.name) AS my_number
FROM
sys.objects a
CROSS JOIN
sys.objects b
)
INSERT INTO my_orders
SELECT my_number1, my_number2
FROM cteTally1 T1 CROSS JOIN cteTally2 T2
WHERE
(T1.my_number1 > 0 AND T1.my_number1 <= 5 ) AND
(T2.my_number2 > 0 AND T2.my_number2 <= 5 );
GO 4
-- Create some data (6-10) x 2 counts
;
WITH cteTally1 (my_number1) AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY a.name) AS my_number
FROM
sys.objects a
CROSS JOIN
sys.objects b
),
cteTally2 (my_number2) AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY a.name) AS my_number
FROM
sys.objects a
CROSS JOIN
sys.objects b
)
INSERT INTO my_orders
SELECT my_number1, my_number2
FROM cteTally1 T1 CROSS JOIN cteTally2 T2
WHERE
(T1.my_number1 >= 6 AND T1.my_number1 <= 10 ) AND
(T2.my_number2 >= 6 AND T2.my_number2 <= 10 );
GO 2
-- Show the data
SELECT * FROM my_orders;
最后但并非最不重要的一点是,一个简单的分组依据将为您计算每个组合的计数。
--
-- Simple group by will suffice
--
SELECT
my_orderstatus_id,
my_orderstage_id,
COUNT(*) as number
FROM my_orders
GROUP BY
my_orderstatus_id,
my_orderstage_id;
GO
输出的快速屏幕截图:
这应该可以解决您的特定问题。但如果我确实弄错了要求,请回帖。
您现在更改了初始要求。这就是我们在管理中所说的范围更改。
如果您知道组合始终为 10 x 10,请创建一个矩阵表或公用表表达式,这样无论匹配如何,您都将始终拥有该组合。
将简单的 group by 扩展到数据的左连接并相应地分组/order by。
--
-- Report Query
--
-- For missing records
;
WITH cteTally1 (my_number1) AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY a.name) AS my_number
FROM
sys.objects a
CROSS JOIN
sys.objects b
),
cteTally2 (my_number2) AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY a.name) AS my_number
FROM
sys.objects a
CROSS JOIN
sys.objects b
),
cteMissingCombos (my_orderstatus_id, my_orderstage_id) AS
(
SELECT T1.my_number1, T2.my_number2
FROM cteTally1 T1 CROSS JOIN cteTally2 T2
WHERE T1.my_number1 < 11 AND T2.my_number2 < 11
)
-- Return null if no records, use coalesce if you want 0
SELECT
C.my_orderstatus_id,
C.my_orderstage_id,
COUNT(O.my_orderstatus_id) as number
FROM
cteMissingCombos as C LEFT JOIN my_orders as O
ON
C.my_orderstatus_id = O.my_orderstatus_id AND
C.my_orderstage_id = O.my_orderstage_id
GROUP BY
C.my_orderstatus_id,
C.my_orderstage_id
ORDER BY
C.my_orderstatus_id,
C.my_orderstage_id
GO
下面的输出表明我们没有 1 x 6 到 10 的组合。因此