Select values from one column and display in two columns - sql

I'm stumped trying to figure out a way to display data from one column in two different columns. The data is a bill of materials in Oracle, and I want to display certain items in the bill of materials in a second column.
For example, I have a master item which is 123ABC. Within this item it has the following items ... AA1, BB1, CC1. They all belong to the same column in the same table.
I'm trying to get a query to to display two columns, the first column would be master item, and the second column would be sub item that shows all items beginning with 'AA' like below...
Master Item | Sub Item
-------------------------
123ABC | AA1
So far I have the following...
select distinct msi.item FNUMBER
, msi.description DESCRIPTION
, (select msi1.item
FROM inv.mtl_sys_item msi1
WHERE msi1.item = msi.item)
from
, .mtl_sys_item msi
where msi.segment1 = '123ABC'
order by 1 desc
But this just displays the master item 'ABC123' in both columns instead of the AA1 in the second column.

Your data must have some sort of parent item column. You can use this to do a self-join:
SELECT msi.item as FNUMBER,
msi.description as DESCRIPTION,
msic.item
FROM inv.mtl_sys_item msi JOIN
inv.mtl_sys_item msic
ON msi.item = msic.parent_item -- guessing at the column name
WHERE msi.segment1 = '123ABC'
ORDER BY 1 desc

Related

Filter with SQL Server by Group ID

I have two tables and I need to filter the data by filter id depends on the relation to to filter group id.
For example I have this two tables:
Table 1:
ItemID
FilterID
3
122
3
123
3
4
17
123
Table 2:
FilterID
FilterGroupID
122
5
123
5
4
1
If I search by filter id = 123 than all item id with this filter need to be returned.
If I search two or more different filter id that have different group id I need to get only the item ids that have all filter id and group id.
Desired output:
first input: 123 -> return item id =3 and item id = 17
second input: 123,4 -> return item id = 3 because filter id 123 belong to group id 5 and filter id 4 belong to group id 1 and item id 3 is the only one that has this two filters.
third input: 122,123 -> return item id =3 and item id = 17 because both filter id belong to same group.
I am getting a little lost with this query and I will be glad to get some help.
I’ll try to simplify it: Let’s say we have group filter of size and group filter of color. If I filter by size S or M than I need to get all items with this sizes. If I want to add color like blue than the answer will cut the result by: item with size S or M and Color blue. So filter from different group may cut some results
It seems that you want to get every ItemID which has at least one matching filter from each FilterGroupID within your filter input. So within each group you have or logic, and between groups you have and logic
If you store your input in a table variable or Table-Valued parameter, then you can just use normal relational division techniques.
This then becomes a question of Relational Division With Remainder, with multiple divisors.
There are many ways to slice this cake. Here is one option
Join the filter input to the groups, to get each filter's group ID
Use a combination of DENSE_RANK and MAX to get the total distinct groups (you can't use COUNT(DISTINCT in a window function so we need to hack it)
You can change this step to use a subquery instead of window functions. It may be faster or slower
Join the main table, and filter out any ItemIDs which do not have their total distinct groups the same as the main total
SELECT
t1.ItemID
FROM (
SELECT *,
TotalGroups = MAX(dr) OVER ()
FROM (
SELECT
fi.FilterID,
t2.FilterGroupID,
dr = DENSE_RANK() OVER (ORDER BY t2.FilterGroupID)
FROM #Filters fi
JOIN Table2 t2 ON t2.FilterID = fI.FilterID
) fi
) fi
JOIN Table1 t1 ON t1.FilterID = fi.FilterID
GROUP BY
t1.ItemID
HAVING COUNT(DISTINCT FilterGroupID) = MAX(fi.TotalGroups);
db<>fiddle

How to arrive rank for the attached data set in SQL using the Date Column for the customers list shown

Friends i want to do rank function for the below set of records considering the maxium Last_transactiondate and assigning it as rank 1 now once i get that i will put No 1 ranks customer has Parent and remaining rank as Childs.
But due to different customerno and different values in other columns i am unable to do effective ranking. kindly help me in this part
I want to rank customers based on LastTransactionDate. consider the LastTransactionDate column, the value '14-06-2019 14:48:24' has the highest record or max date Hence the corresponding CustomerNo should be picked has Parent and rest should be tagged as child. If only if i could rank CustomerNo 0003178419452479 as rank 1 and then subsequent ranks in the descending order which i am unable to do. I cannot find Column not derive a column which exist with same value for all customers to put rank based on the Date column.
The code i have written and the output is shown here
enter image description here
Also the output Image shown here is the required output want from the above data set image
code
> SELECT CustomerNO,CustomerID,CustomerIDType,CustomerNationalityCode,CustomerDateOfBirth,LastTransactionDate,Class_Profile,
,Dense_Rank() over ( PARTITION BY n.CustomerNO ORDER BY LastTransactionDate DESC ) AS ranks,
case when ranks=1 then 'P' else 'C' end as Class_Profile
FROM CustomerTabledetails
GROUP BY CustomerNo,CustomerID,CustomerIDType,
CustomerNationalityCode,CustomerDateOfBirth,LastTransactionDate,Class_Profile
order by lasttransactiondate desc

Oracle: how to group by 1st value in row?

Table has 3 columns in a table: ITEM, SUB_ITEM, DATE_CREATED.
ITEM - item id (string)
SUB_ITEM - item id (int)
DATE_CREATE - date the SUB_ITEM was created (date)
Scenario:
There are 3 Different item's (AAA1, AAB2, ABB3)
All 3 of these item's have multiple sub-items.
Each item has a sub-item that is the same for each of them (eg. All 3 of the item's have a SUB_ITEM = 101010)
I am trying to do something like:
select *
from table
group by ITEM, SUB_ITEM, DATE_CREATED
How do you make it display only 1 row? I don't care if it chooses AAA1 or AAB2 or ABB3, I just want it to pick 1 and remove the rest so it will show 1 row per SUB_ITEM, but still displays at least one of the parent items.
Edit:
Thank you to mathguy for answering the above question.
Question 2:
Is it possible to group by the 1st 2 letters of the item in addition to the sub_item? So instead of returning 1 row, return 2 rows: AAA1 and AAB2 will cascade in to 1 row, and ABB3 will be the 2nd row because 'AA' and 'AB' are different.
Edit 2: See Main Answer comments for answer to question 2
One way is to group by sub_item, and take the max or min over another column (let's say max over date_created) and whatever is in the remaining column IN THE SAME ROW.
select min(item) keep (dense_rank last order by date_created) as item,
sub_item, max(date_created) as date_created
from table_name
group by sub_item
;

Pull distinct value to show oldest date and nested with certain criteria SQL

Item dateordered codeordered
A 3/5/12 old
A 1/1/14 regular
A 2/1/13 notregular
B 4/5/13 regular
I’d like to create a syntax that pulls distinct for :
Oldest date items got ordered (A and B), which has the codeordered in (regular or old) only.
So my desired result is:
Item A, dateordered 3/5/12
Item B, dateordered 4/5/13
I tried to create temporary table, and pulled mindistinct for dateordered from it, but for item A it still pulls both days of 3/5/12 and 1/1/14.
I believe you are looking for this:
SELECT
Item,
MIN(DateOrdered) EarliestOrderDate
FROM the_table
WHERE CodeOrdered IN ('Regular', 'Old')
GROUP BY Item

In Excel how to create multiple rows from a single data row

I have an execl datasheet with data looking like this
id desc part no 1 Qty 1 part no 2 Qty 2 part no 3 Qty 3
1 PartsName 382A012-3-0 3 382A023-3 3 382A012-25 3
And need it to look like this
id desc part no Qty
1 PartsName 382A012-3-0 3
1 PartsName 382A023-3/42-0 3
1 PartsName 382A012-25/86-0 3
This from a SQL Table so I could do it in SQL if that makes it easier
Anybody any suggestions as how to best to sort this?
Simply make a UNION in the SQL
SELECT id, desc, partNo, qty FROM parts
UNION SELECT id, desc, partNo2 as partNo, qty2 as qty FROM parts
UNION SELECT id, desc, partNo3 as partNo, qty3 as qty FROM parts
ORDER BY id
If you don´t have the option of using SQL and need to use Excel. You can use the TRANSPOSE function. It is an array type function so you need to use the {}. If you haven´t used it before I recommend reading the help first. I however don´t think you can use transpose to get it exactly as you describe it. The id and desc column have to handled separately.
You need to add next formulas on a new sheet:
column A=MOD(ROW()+1,3)
it's like a skeleton :)
First row is headers
column B
=IF($A2=0,OFFSET(Sheet1!$A$1,COUNTIF($A$2:$A2,0),COLUMN()-2),B1)
autofil col C with it
column D
=OFFSET(Sheet1!$A$1,COUNTIF($A$2:$A2,0),COLUMN()+CHOOSE($A2+1,-2,0,2))
autofil col E with it
one more - your datasheet is "sheet1"