我的查询数据设计如下表所示:
SHIPMENT_NO SHIPMENT_DATE PART_NAME BOX_NUMBER
DG3-14040001 4/24/2014 TEST S201551254
DG3-14040001 4/24/2014 TEST S010101010
DG3-14040001 4/24/2014 TEST S100200123
DG2-14040001 4/24/2014 DG-M11-A S001545525
我想要的是:
SHIPMENT_NO SHIPMENT_DATE PART_NAME BOX_NUMBER
DG3-14040001 4/24/2014 TEST S201551254
4/24/2014 TEST S010101010
4/24/2014 TEST S100200123
DG2-14040001 4/24/2014 DG-M11-A S001545525
因为发货没有DG3-14040001相同,所以它只会显示1个值。
这是My Oracle SQL:
SELECT SHIPMENT_NO, SHIPMENT_DATE, PART_NAME, BOX_NUMBER FROM DIGI_SHIPMENT_SCAN WHERE TO_CHAR(SHIPMENT_DATE,'YYYY-MM-DD') BETWEEN '$start_date' AND '$end_date' GROUP BY SHIPMENT_NO, SHIPMENT_DATE, PART_NAME, BOX_NUMBER
while($d1 = oci_fetch_array($result_q1))
{
$shp_no = $d1['SHIPMENT_NO'];
$shp_date = $d1['SHIPMENT_DATE'];
$part_name = $d1['PART_NAME'];
$box_number = $d1['BOX_NUMBER'];
SELECT COUNT(*) AS TOTAL_SHP FROM DIGI_SHIPMENT_SCAN WHERE TO_CHAR(SHIPMENT_DATE,'YYYY-MM-DD') BETWEEN '$start_date' AND '$end_date' AND SHIPMENT_NO = '$shp_no'
$result_q3 = oci_parse($c1, $q3);
oci_execute($result_q3);
$d3 = oci_fetch_array($result_q3);
$total_shp = $d3['TOTAL_SHP'];
<td class="td_brd7 td_brd6" rowspan="<?php echo $total_shp; ?>"><?php echo $shp_no; ?></td>
<td class="td_brd7 td_brd6" rowspan="<?php echo $total_shp; ?>"><?php echo $shp_date; ?></td>
<td class="td_brd7 td_brd6" rowspan="<?php echo $total_shp; ?>"><?php echo $part_name; ?></td>
<td class="td_brd7 td_brd6" rowspan="<?php echo $total_shp; ?>"><?php echo $box_number; ?></td>
}
当结果出现时,它将显示Double Shipment No取决于BOX Number总行查询。
您可以在图片上看到,出货号应该显示1值,因为相同的值。
请提供建议。
答案 0 :(得分:0)
这通常应该在您的应用程序逻辑中完成,但也可以通过巧妙地使用LAG()函数来完成。
LAG()允许您根据特定顺序评估上一行。然后,当它与前一行相同时,可以应用CASE WHEN显示NULL。
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions070.htm
示例:
SELECT CASE WHEN LAG(Shipment_No)
OVER (ORDER BY Shipment_No, Order_Date) = Shipment_NO
THEN NULL ELSE Shipment_No END AS Shipment_NO,
(...)
FROM YourTable
ORDER BY Shipment_No, Order_Date;
答案 1 :(得分:0)
这种格式化确实应该在应用程序级别完成,即使在SQL中也是如此。从表的一行中删除值会使结果不再是关系数据集。
您可以使用LAG()
:
SELECT (CASE WHEN SHIPMENT_NO = LAG(SHIPMENT_NO) OVER (ORDER BY SHIPMENT_NO, SHIPMENT_DATE, PART_NAME, BOX_NUMBER) AND
SHIPMENT_DATE = LAG(SHIPMENT_DATE) OVER (ORDER BY SHIPMENT_NO, SHIPMENT_DATE, PART_NAME, BOX_NUMBER) AND
PART_NAME = LAG(PART_NAME) OVER (ORDER BY SHIPMENT_NO, SHIPMENT_DATE, PART_NAME, BOX_NUMBER)
THEN ''
ELSE SHIPMENT_NO
END) as SHIPMENT_NO,
DSS.SHIPMENT_DATE, DSS.PART_NAME, DSS.BOX_NUMBER
FROM DIGI_SHIPMENT_SCAN DSS
WHERE TO_CHAR(SHIPMENT_DATE,'YYYY-MM-DD') BETWEEN '$start_date' AND '$end_date'
GROUP BY DSS.SHIPMENT_NO, DSS.SHIPMENT_DATE, DSS.PART_NAME, DSS>BOX_NUMBER
ORDER BY DSS.SHIPMENT_NO, DSS.SHIPMENT_DATE, DSS.PART_NAME, DSS.BOX_NUMBER;
这样做需要处理一些细微之处。输出需要明确排序。除非包含order by
子句,否则不能依赖结果集的顺序。然后,您需要对lag()
使用相同的顺序,而不使用partition by
子句。
请注意,查询还使用表别名。这是因为列别名SHIPMENT_NO
可能与DSS.SHIPMENT_NO
子句中的列order by
混淆。您需要具体,或者所有空白列将一起显示。
答案 2 :(得分:0)
如何使用break on
?
break on SHIPMENT_NO;
SELECT SHIPMENT_NO, SHIPMENT_DATE, PART_NAME, BOX_NUMBER
FROM DIGI_SHIPMENT_SCAN WHERE
TO_CHAR(SHIPMENT_DATE,'YYYY-MM-DD')
BETWEEN '$start_date' AND '$end_date' GROUP BY
SHIPMENT_NO, SHIPMENT_DATE, PART_NAME, BOX_NUMBER
http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch6.htm
禁止中断列中的重复值
BREAK
命令默认在您命名的列或表达式中禁止重复值。因此,要抑制ORDER BY
子句中指定的列中的重复值,请以最简单的形式使用BREAK
命令:
BREAK ON break_column
注意:
无论何时在BREAK
命令中指定列或表达式,请使用指定相同列或表达式的ORDER BY
子句。如果不这样做,每次列值更改时都会发生中断。
示例6-10抑制中断列中的重复值
要在显示的查询结果中禁止显示重复的部门编号,请输入以下命令:
BREAK ON DEPARTMENT_ID;
对于以下查询(存储在缓冲区中的当前查询):
SELECT DEPARTMENT_ID, LAST_NAME, SALARY
FROM EMP_DETAILS_VIEW
WHERE SALARY > 12000
ORDER BY DEPARTMENT_ID;
DEPARTMENT_ID LAST_NAME
SALARY
------------- ------------------------- ----------
20 Hartstein 13000
80 Russell 14000
Partners 13500
90 King 24000
Kochhar 17000
De Haan 17000
6 rows selected.