如何在SQL中连接两个没有关系的表

如何在SQL中连接两个没有关系的表,sql,postgresql,outer-join,Sql,Postgresql,Outer Join,我正在努力将三个表与外部联接结合起来,但无法正确进行 我正在使用PostgreSQL数据库。。 我的桌子是这样的: 我的订单表有客户和年份的外键(这两者没有任何关系) 某些年份和客户未显示在我的订单表中 我正在尝试进行sql查询,这样每个客户都可以全年查询。我可以通过交叉连接customer和year来获得这个结果,但当我继续将这个结果与其他表连接时,这种方法不起作用。(我的Orders表还有其他外键,我也必须连接它们)因此我可以使用外部连接来获得这个结果吗 我试过: Select* From

我正在努力将三个表与外部联接结合起来,但无法正确进行 我正在使用PostgreSQL数据库。。 我的桌子是这样的:

我的订单表有客户和年份的外键(这两者没有任何关系) 某些年份和客户未显示在我的订单表中 我正在尝试进行sql查询,这样每个客户都可以全年查询。我可以通过交叉连接customer和year来获得这个结果,但当我继续将这个结果与其他表连接时,这种方法不起作用。(我的Orders表还有其他外键,我也必须连接它们)因此我可以使用外部连接来获得这个结果吗

我试过:

Select* From Orders
RIGHT JOIN Customers on Orders.customer_id = customer.id
这给了我订单表中的所有客户(即使他们没有发送订单),然后我也希望对所有年份执行相同的操作,因此每个客户每年都有一行(2015-2020年)尝试使用年份表进行另一次正确的连接,但它确实有效。。有人知道怎么解决这个问题吗


p、 s表的名称不是真实的,我只是用这个名称让它更容易理解

A
客户和年份的交叉加入,然后A
订单的左加入,似乎与您在帖子中描述的完全一样。还是我做错了什么

下次不要将数据放入图像中。只需将其键入/粘贴到您的帖子中,我们就可以将其复制粘贴到我们的示例中。。。我不得不重新打字

“姓名”和“年份”是保留字。在我的例子中,我避开了它们

\pset null NULL
WITH 
-- your input ...
customers ( id, nm) AS (
          SELECT 1,'alpha'
UNION ALL SELECT 2,'bravo'
UNION ALL SELECT 3,'charlie'
UNION ALL SELECT 4,'delta'
UNION ALL SELECT 5,'echo'
UNION ALL SELECT 6,'foxtrot'
)
,
years(id,yr) AS (
          SELECT 1,2015
UNION ALL SELECT 2,2016
UNION ALL SELECT 3,2017
UNION ALL SELECT 4,2018
UNION ALL SELECT 5,2019
UNION ALL SELECT 6,2020
)
,
orders(id,cust_id,yr_id) AS (
          SELECT 1,1,1
UNION ALL SELECT 2,2,3
UNION ALL SELECT 3,4,5
UNION ALL SELECT 4,5,6
)
-- end of your input ...
SELECT
  cust.nm
, years.yr
, ord.id
FROM customers cust
CROSS JOIN years
LEFT JOIN orders ord ON ord.yr_id=years.id
ORDER BY 1,2
;
-- out    nm    |  yr  |  id  
-- out ---------+------+------
-- out  alpha   | 2015 |    1
-- out  alpha   | 2016 | NULL
-- out  alpha   | 2017 |    2
-- out  alpha   | 2018 | NULL
-- out  alpha   | 2019 |    3
-- out  alpha   | 2020 |    4
-- out  bravo   | 2015 |    1
-- out  bravo   | 2016 | NULL
-- out  bravo   | 2017 |    2
-- out  bravo   | 2018 | NULL
-- out  bravo   | 2019 |    3
-- out  bravo   | 2020 |    4
-- out  charlie | 2015 |    1
-- out  charlie | 2016 | NULL
-- out  charlie | 2017 |    2
-- out  charlie | 2018 | NULL
-- out  charlie | 2019 |    3
-- out  charlie | 2020 |    4
-- out  delta   | 2015 |    1
-- out  delta   | 2016 | NULL
-- out  delta   | 2017 |    2
-- out  delta   | 2018 | NULL
-- out  delta   | 2019 |    3
-- out  delta   | 2020 |    4
-- out  echo    | 2015 |    1
-- out  echo    | 2016 | NULL
-- out  echo    | 2017 |    2
-- out  echo    | 2018 | NULL
-- out  echo    | 2019 |    3
-- out  echo    | 2020 |    4
-- out  foxtrot | 2015 |    1
-- out  foxtrot | 2016 | NULL
-- out  foxtrot | 2017 |    2
-- out  foxtrot | 2018 | NULL
-- out  foxtrot | 2019 |    3
-- out  foxtrot | 2020 |    4

如果您希望所有客户都有一年的订单,如果他们每年都有订单,那么他们各自的订单

SELECT CUS.ID AS CustomerID, CUS.Name AS CustomerName, YEA.year AS Year, ORD.ID AS OrderID 
FROM Customers AS CUS
   CROSS JOIN Years AS YEA
   LEFT JOIN Orders AS ORD 
        ON CUS.ID = ORD.Customer_ID
        AND ORD.YEAR_ID = YEA.ID;
这将给你和他们的订单作为单独的行。 如果您想要订单数量,请使用此选项:

SELECT CUS.ID AS CustomerID, CUS.Name AS CustomerName, YEA.year AS Year, Count(ORD.ID) AS NrOfOrders 
FROM Customers AS CUS
   CROSS JOIN Years AS YEA
   LEFT JOIN Orders AS ORD 
        ON CUS.ID = ORD.Customer_ID
        AND ORD.YEAR_ID = YEA.ID
GROUP BY CUS.ID, CUS.Name, YEA.Year;
这将显示订单数量,并每年给每个客户一行

SELECT CUS.ID AS CustomerID, CUS.Name AS CustomerName, YEA.year AS Year, ORD.ID AS OrderID 
FROM Customers AS CUS
   CROSS JOIN Years AS YEA
   LEFT JOIN Orders AS ORD 
        ON CUS.ID = ORD.Customer_ID
        AND ORD.YEAR_ID = YEA.ID;

试试/看看它的实际效果,我添加了一些数据来显示多个订单。

Thx D Kramer,这很好。我没有添加这样的内容:“AND ORD.YEAR\u ID=YEA.ID”当我之前做交叉连接时,这是我问题的解决方案:-)对于输入marcothesane,我之前尝试交叉连接时忘记在交叉连接中添加一行。现在它工作了。将如您下次指出的那样添加数据,您可以看到这将如何生成更多场景:-)