Oracle SQL-表与不正确数据输出之间的1:M关系上的左联接
我想使用左连接连接多个表。我当前在连接中获得重复记录和不一致的数据。有什么想法吗 我相信我找到了解决重复记录的方法,但我不确定它是否可靠 在本例中,下订单时,应将其附加到与订单关联的任何项目以及与发票关联的任何客户端。Items和Client表基本上是静态的,只有在添加新的Items或Client时才会更新,这并不常见 这是一个小规模的例子,整个数据集大约有600万行 订单与订单详细程度的关系为1:M 发票与订单的关系为M:1,与订单详细程度的关系为M:M 客户端仅与具有1:1关系的发票关联 项目与订单详细信息的关系为1:MOracle SQL-表与不正确数据输出之间的1:M关系上的左联接,sql,oracle,join,distinct,Sql,Oracle,Join,Distinct,我想使用左连接连接多个表。我当前在连接中获得重复记录和不一致的数据。有什么想法吗 我相信我找到了解决重复记录的方法,但我不确定它是否可靠 在本例中,下订单时,应将其附加到与订单关联的任何项目以及与发票关联的任何客户端。Items和Client表基本上是静态的,只有在添加新的Items或Client时才会更新,这并不常见 这是一个小规模的例子,整个数据集大约有600万行 订单与订单详细程度的关系为1:M 发票与订单的关系为M:1,与订单详细程度的关系为M:M 客户端仅与具有1:1关系的发票关联 项
选择DISTINCT
(按a.apk顺序按a.apk desc分区)上的行数()作为SEQNUM
从桌子上
其中SEQNUM=1
当前解决方案
SELECT DISTINCT
a.apk
,a.DATE
,bc.CATEGORY
,bc.ITEMNAME
,bc.amt
,d.clientname
,e.invoiceid
,row_number() over (partition by a.apk order by a.apk desc) as SEQNUM
FROM atable a
LEFT JOIN
(SELECT DISTINCT
tableb.amt
,tableb.apk
,tablec.CATEGORY
,tablec.ITEMNAME
FROM tableb b
LEFT JOIN tablec c ON (b.cpk = c.cpk)) bc
ON (a.apk = bc.apk)
LEFT JOIN
(SELECT DISTINCT
d.clientname
,e.invoiceid
,e.epk
,d.dpk
FROM tabled d
LEFT JOIN tableE e ON (d.dpk = e.epk)) ed
ON (a.apk = ed.apk)
WHERE SEQNUM = 1
样本数据
表A(订单)主键:apk
apk DATE
1 8/17/17
bpk apk cpk amt
1 1 1 5
2 1 2 100
cpk ITEMNAME ITEMID CATEGORY
1 Tape 1234 Office Supplies
2 Toner 5678 Printer Supplies
epk apk dpk INVOICEID INVOICE_DATE
1 1 5 776 8/18/17
2 1 6 934 8/19/17
表B(订单详细程度)主键:bpk
apk DATE
1 8/17/17
bpk apk cpk amt
1 1 1 5
2 1 2 100
cpk ITEMNAME ITEMID CATEGORY
1 Tape 1234 Office Supplies
2 Toner 5678 Printer Supplies
epk apk dpk INVOICEID INVOICE_DATE
1 1 5 776 8/18/17
2 1 6 934 8/19/17
表C(项目)主键:cpk
apk DATE
1 8/17/17
bpk apk cpk amt
1 1 1 5
2 1 2 100
cpk ITEMNAME ITEMID CATEGORY
1 Tape 1234 Office Supplies
2 Toner 5678 Printer Supplies
epk apk dpk INVOICEID INVOICE_DATE
1 1 5 776 8/18/17
2 1 6 934 8/19/17
表D(客户端)主键:dpk
dpk CLIENTNAME
5 STAPLES
6 WALMART
表E(发票)主键:epk
apk DATE
1 8/17/17
bpk apk cpk amt
1 1 1 5
2 1 2 100
cpk ITEMNAME ITEMID CATEGORY
1 Tape 1234 Office Supplies
2 Toner 5678 Printer Supplies
epk apk dpk INVOICEID INVOICE_DATE
1 1 5 776 8/18/17
2 1 6 934 8/19/17
当前结果
apk DATE CATEGORY ITEMNAME amt CLIENTNAME INVOICEID
1 8/17/17 Office Supplies Tape 5 Staples 776
1 8/17/17 Office Supplies Tape 100 Walmart 934
1 8/17/17 Office Supplies Tape 5 Staples 776
1 8/17/17 Office Supplies Tape 100 Walmart 934
1 8/17/17 Office Supplies Tape 100 Walmart 934
1 8/17/17 Office Supplies Tape 100 Walmart 934
预期结果
apk DATE CATEGORY ITEMNAME amt CLIENTNAME INVOICEID
1 8/17/17 Office Supplies Tape 5 Staples 776
1 8/17/17 Printer Supplies Toner 100 Walmart 934
提前谢谢
编辑:数据,澄清如果我们假设发票表有cpk列
Table E (Invoice) Primary Key: epk
epk apk cpk dpk INVOICEID
1 1 1 5 776
2 1 2 6 934
SQL查询将是
SELECT os.apk,
os.ord_dt,
it.category,
it.itemname,
od.amt,
cs.clientname,
ie.invoiceid
FROM orders os
INNER JOIN order_dtl od
ON os.apk = od.apk
INNER JOIN items it
ON od.cpk = it.cpk
INNER JOIN invoice ie
ON ie.apk = od.apk
AND ie.cpk = od.cpk
INNER JOIN clients cs
ON cs.dpk = ie.dpk;
结果
APK ORD_DT CATEGORY ITEMNAME AMT CLIENTNAME INVOICEID
---------- --------- -------------------- ---------- ---------- ---------- ----------
1 17-AUG-17 Office Supplies Tape 5 STAPLES 776
1 17-AUG-17 Printer Supplies Toner 100 WALMART 934
我认为您应该将
bpk
添加到invoice
表中,或者将epk
添加到order details
中,以便在这些表之间建立连接。否则我们不知道碳粉是史泰博还是沃尔玛订购的
但在当前数据模型中,假设订单详细信息中的第一个项目与发票中的第一个位置匹配,我们可以使用行编号()。我所说的“第一”是指id较低的:
select apk, adate, category, itemname, amt, clientname, invoiceid
from a
join (select b.*, row_number() over (partition by apk order by bpk) rn
from b) b using (apk)
join c using (cpk)
join (select e.*, row_number() over (partition by apk order by epk) rn
from e) e using (apk, rn)
join d using (dpk)
演示:
结果:
APK ADATE CATEGORY ITEMNAME AMT CLIENTNAME INVOICEID
------ ----------- ---------------- -------- ---------- ---------- ----------
1 2017-08-17 Office Supplies Tape 5 Staples 776
1 2017-08-17 Printer Supplies Toner 100 Wallmart 934
我不明白您是如何决定在预期结果的最后两个属性中选择值的。apk有两个选项(staples和wallmart),因此,为什么第一行有staples,第二行有walmart,第二行有偶数赏金(加上属于walmart的934)?实际上,如果只执行内部联接,则得到6行。你的回答不清楚你的预期结果是如何产生的。这个问题毫无意义。例如,在您的表数据中,“磁带”的cpk=1,已知一个金额值:3,但在您当前和所需的输出中,您将“磁带”的数量链接为5。“纸巾”的数量仅为100,但在您想要的输出中,您想要3@RadimBača我们的数据就是这样在我这边建立的。例如,一张发票可能包含多个项目,每个项目都与一个客户关联。我试图复制我这边的样子。对这里的任何混乱表示歉意。为了澄清,我删除了第三项。@trincot我删除了第三项并进行了相应调整。我只是不明白为什么在提取任何数据时,它会在所有行上提取不正确的项目名称和类别。