I have 2 tables, tableStock and tableParts:
tableStock
+----+----------+-------------+
| ID | Num_Part | Description |
+----+----------+-------------+
| 1 | sr37 | plate |
+----+----------+-------------+
| 2 | sr56 | punch |
+----+----------+-------------+
| 3 | sl30 | crimper |
+----+----------+-------------+
| 4 | mp11 | holder |
+----+----------+-------------+
tableParts
+----+----------+-------+
| ID | Location | Stock |
+----+----------+-------+
| 1 | A | 2 |
+----+----------+-------+
| 3 | B | 5 |
+----+----------+-------+
| 5 | C | 2 |
+----+----------+-------+
| 7 | A | 1 |
+----+----------+-------+
And I just want to do this:
+----+----------+-------------+----------+-------+
| ID | Num_Part | Description | Location | Stock |
+----+----------+-------------+----------+-------+
| 1 | sr37 | plate | A | 2 |
+----+----------+-------------+----------+-------+
| 2 | sr56 | punch | NULL | NULL |
+----+----------+-------------+----------+-------+
| 3 | sl30 | crimper | B | 5 |
+----+----------+-------------+----------+-------+
| 4 | mp11 | holder | NULL | NULL |
+----+----------+-------------+----------+-------+
List ALL the rows of the first table and if the second table has the info, in this case 'location' and 'stock', add to the column, if not, just null.
I have been using inner and left join but some rows of the first table disappear because the lack of data in the second one:
select tableStock.ID, tableStock.Num_Part, tableStock.Description, tableParts.Location, tableParts.Stock from tableStock inner join tableParts on tableStock.ID = tableParts.ID;
What can I do?
You can use left join. Here is the demo.
select
s.ID,
Num_Part,
Description,
Location,
Stock
from Stock s
left join Parts p
on s.ID = p.ID
order by
s.ID
output:
| id | num_part | description | location | stock |
| --- | -------- | ----------- | -------- | ----- |
| 1 | sr37 | plate | A | 2 |
| 2 | sr56 | punch | NULL | NULL |
| 3 | sl30 | crimper | B | 5 |
| 4 | mp11 | holder | NULL | NULL |
I have table for eg "employee" with just one column "id". Say you have records from 1 through 1000.
Employee
------------
ID
------------
1
2
3
..
..
999
1000
Now I would like to write a query which gives the following results i.e. sort by ascending order and concatenate first 5 to 1 record, second 5 to 2 second, and so on. Any ideas how I can do this?
Here is the output I am looking to have.
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
...........
...........
996,997,998,999,1000
Use row_number and listagg functions, in this way:
SELECT listagg( id, ',' ) within group( order by group_no, id )
FROM (
select id,
trunc((row_number() over( order by id ) -1) / 5) as group_no
from employee
)
GROUP BY group_no
Working demo: http://sqlfiddle.com/#!4/ef526/10
| LISTAGG(ID,',')WITHINGROUP(ORDERBYGROUP_NO,ID) |
|------------------------------------------------|
| 1,2,3,4,5 |
| 6,7,8,9,10 |
| 11,12,13,14,15 |
| 16,17,18,19,20 |
| 21,22,23,24,25 |
| 26,27,28,29,30 |
| 31,32,33,34,35 |
| 36,37,38,39,40 |
| 41,42,43,44,45 |
| 46,47,48,49,50 |
| 51,52,53,54,55 |
| 56,57,58,59,60 |
| 61,62,63,64,65 |
| 66,67,68,69,70 |
| 71,72,73,74,75 |
| 76,77,78,79,80 |
| 81,82,83,84,85 |
| 86,87,88,89,90 |
| 91,92,93,94,95 |
| 96,97,98,99,100 |
| 101,102,103,104,105 |
| 106,107,108,109,110 |
| 111,112,113,114,115 |
| 116,117,118,119,120 |
| 121,122,123,124,125 |
| 126,127,128,129,130 |
| 131,132,133,134,135 |
| 136,137,138,139,140 |
| 141,142,143,144,145 |
| 146,147,148,149,150 |
| 151,152,153,154,155 |
| 156,157,158,159,160 |
| 161,162,163,164,165 |
| 166,167,168,169,170 |
| 171,172,173,174,175 |
| 176,177,178,179,180 |
| 181,182,183,184,185 |
| 186,187,188,189,190 |
| 191,192,193,194,195 |
| 196,197,198,199,200 |
I have a base table where I need to calculate the difference between two dates based on the type of the entry.
tblA
+----------+------------+---------------+--------------+
| TypeCode | Log_Date | Complete_Date | Pending_Date |
+----------+------------+---------------+--------------+
| 1 | 18/04/2016 | 19/04/2016 | |
| 2 | 10/04/2016 | 18/04/2016 | 15/04/2016 |
| 3 | 12/04/2016 | 19/04/2016 | |
| 4 | 15/04/2016 | 17/04/2016 | 16/04/2016 |
| 5 | 16/04/2016 | 21/04/2016 | |
| 1 | 19/04/2016 | 20/04/2016 | |
| 2 | 20/03/2016 | 31/03/2015 | |
| 3 | 25/03/2016 | 28/03/2016 | |
| 4 | 26/03/2016 | 27/03/2016 | |
| 5 | 27/03/2016 | 30/03/2016 | |
+----------+------------+---------------+--------------+
I have another look up table which has the column names to be considered based on the TypeCode.
tblB
+----------+----------+---------------+
| TypeCode | DateCol1 | DateCol2 |
+----------+----------+---------------+
| 1 | Log_Date | Complete_Date |
| 2 | Log_Date | Pending_Date |
| 3 | Log_Date | Complete_Date |
| 4 | Log_Date | Pending_Date |
| 5 | Log_Date | Complete_Date |
+----------+----------+---------------+
I am doing a simple DATEDIFF between two dates for my calculation. However I want to lookup which columns to consider for this calculation from tblB and apply it on tblA based on the TypeCode.
Resulting table:
For example: When the TypeCode is 2 or 4 then the calculation should be DATEDIFF(d, Log_Date, Pending_Date), otherwise DATEDIFF(d, Log_Date, Complete_Date)
+----------+------------+---------------+--------------+----------+
| TypeCode | Log_Date | Complete_Date | Pending_Date | Cal_Days |
+----------+------------+---------------+--------------+----------+
| 1 | 18/04/2016 | 19/04/2016 | | 1 |
| 2 | 10/04/2016 | 18/04/2016 | 15/04/2016 | 5 |
| 3 | 12/04/2016 | 19/04/2016 | | 7 |
| 4 | 15/04/2016 | 17/04/2016 | 16/04/2016 | 1 |
| 5 | 16/04/2016 | 21/04/2016 | | 5 |
| 1 | 19/04/2016 | 20/04/2016 | | 1 |
| 2 | 20/03/2016 | 31/03/2015 | | |
| 3 | 25/03/2016 | 28/03/2016 | | 3 |
| 4 | 26/03/2016 | 27/03/2016 | | |
| 5 | 27/03/2016 | 30/03/2016 | | 3 |
+----------+------------+---------------+--------------+----------+
Any help would be appreciated. Thanks.
Use JOIN with CASE expression:
SELECT
a.*,
Cal_Days =
DATEDIFF(
DAY,
CASE
WHEN b.DateCol1 = 'Log_Date' THEN a.Log_Date
WHEN b.DateCol1 = 'Complete_Date' THEN a.Complete_Date
ELSE a.Pending_Date
END,
CASE
WHEN b.DateCol2 = 'Log_Date' THEN a.Log_Date
WHEN b.DateCol2 = 'Complete_Date' THEN a.Complete_Date
ELSE a.Pending_Date
END
)
FROM TblA a
INNER JOIN TblB b
ON b.TypeCode = a.TypeCode
I have a table which represents the hierarchy of departments:
+-----------+--------------+--------------+--------------+-----------+-------+
| Top Dept. | 2-tier Dept. | 3-tire Dept. | 4-tier Dept. | name | tier |
+-----------+--------------+--------------+--------------+-----------+-------+
| 00 | | | | abc | 0 |
| | 00-01 | | | bcd | 1 |
| | | 00-01-01 | | cde | 2 |
| | | 00-01-02 | | abc | 2 |
| | 00-02 | | | aef | 1 |
| | | 00-02-01 | | qwe | 2 |
| | | 00-02-03 | | abc | 2 |
| | | | 00-02-03-01 | abc | 3 |
+-----------+--------------+--------------+--------------+-----------+-------+
now I want to sort the rows which are in the same tier by their names while keeping the hierarchy overall, That's what I expect:
+-----------+--------------+--------------+--------------+-----------+-------+
| Top Dept. | 2-tier Dept. | 3-tire Dept. | 4-tier Dept. | name | tier |
+-----------+--------------+--------------+--------------+-----------+-------+
| 00 | | | | abc | 0 |
| | 00-02 | | | aef | 1 |
| | | 00-02-03 | | abc | 2 |
| | | 00-02-01 | | qwe | 2 |
| | 00-01 | | | def | 1 |
| | | 00-01-02 | | abc | 2 |
| | | 00-01-01 | | cde | 2 |
| | | | 00-02-03-01 | abc | 3 |
+-----------+--------------+--------------+--------------+-----------+-------+
the missing data means null, I'm using Oracle DB, can anyone help me?
EDIT: Actually, it's a simple version of this sql, I've tried to add a new column which concats the values of the first four columns and then order by it and by name, but it did't work.
Update: This appears to be working... SQL Fiddle
All that was really needed from my original comment was to amend name to department in that order in both selects. This allows the engine to sort by name first, while maintaining the hierarchy.
WITH cte(Dept, superiorDept, name, depth, sort)AS (
SELECT
Dept,
superiorDept,
name,
0,
name|| dept
FROM hierarchy h
WHERE superiorDept IS NULL
UNION ALL
SELECT
h2.Dept,
h2.superiorDept,
h2.name,
cte.depth + 1,
cte.sort || h2.name ||h2.dept
FROM hierarchy h2
INNER JOIN cte ON h2.superiorDept = cte.Dept
)
SELECT
CASE WHEN depth = 0 THEN Dept END AS 一级部门,
CASE WHEN depth = 1 THEN Dept END AS 二级部门,
CASE WHEN depth = 2 THEN Dept END AS 三级部门,
CASE WHEN depth = 3 THEN Dept END AS 四级部门,
name,
depth,
sort
FROM cte
ORDER BY sort, name