SQL concat function, combine size and colour - sql

If there is a table called variant
id slug slug_id
------- --------- ----------
1 s 10
1 m 10
1 l 10
1 black 11
1 pink 11
1 ship_us 12
1 ship_uk 12
2 xl 10
2 xxl 10
2 blue 11
2 white 11
Result I need in this format:
id variant_slug
-------- ------------
1 1-s-black-ship_us
1 1-s-black-ship_uk
1 1-s-pink-ship_us
1 1-s-pink-ship_uk
1 1-m-black-ship_us
1 1-m-black-ship_uk
1 1-m-pink-ship_us
1 1-m-pink-ship_uk
1 1-l-black-ship_us
1 1-l-black-ship_uk
1 1-l-pink-ship_us
1 1-l-pink-ship_uk
2 2-xl-blue
2 2-xl-white
2 2-xxl-blue
2 2-xxl-white
Q: this record is in same variant table. I have almost no experience using UDFs, stored procedures, I need to be done this thing through query. Is this possible without using UDFs, SP's.

Perhaps a self-join assuming the length of size<=3.
Select A.ID
,variant_slug = concat(A.id,'-',A.slug,'-',B.slug)
from YourTable A
Join YourTable B
on A.ID=B.ID
and A.slug<>B.slug
and len(B.slug)>3
and len(A.slug)<=3
Results
ID variant_slug
1 1-l-black
1 1-l-pink
1 1-m-black
1 1-m-pink
1 1-s-black
1 1-s-pink
2 2-xl-blue
2 2-xl-white
2 2-xxl-blue
2 2-xxl-white
Rather than len(), you can enumerate the sizes i.e. {NOT } IN ('s','m','l','xl','xxl')
Select A.ID
,variant_slug = concat(A.id,'-',A.slug,'-',B.slug)
from YourTable A
Join YourTable B
on A.ID=B.ID
and A.slug<>B.slug
and B.slug NOT IN ('s','m','l','xl','xxl')
and A.slug IN ('s','m','l','xl','xxl')

You can go for INNER JOIN by separating the table into two separate tables: size, color and get the variant data, as given below:
declare #slug table(id int, slug varchar(100))
insert into #slug values
(1,'s')
,(1,'m')
,(1,'l')
,(1,'black')
,(1,'pink')
,(2,'xl')
,(2,'xxl')
,(2,'blue')
,(2,'white');
SELECT size.id, CONCAT_WS('-',size.id,size.size, color.color) as variant_size
from (select id,slug as size from #slug where slug in ('s','m','l','xl','xxl') ) as size
INNER JOIN (select id,slug as color from #slug where slug NOT in ('s','m','l','xl','xxl') ) as COLOR
on color.id = size.id
id
variant_size
1
1-s-black
1
1-s-pink
1
1-m-black
1
1-m-pink
1
1-l-black
1
1-l-pink
2
2-xl-blue
2
2-xl-white
2
2-xxl-blue
2
2-xxl-white

Related

How to compare each group of one table with a column in another table?

I have two tables:
TypeTable
TypeId PersonClassificationId
----------------------
1 1
1 2
1 3
2 1
2 2
PersonClassificationTable
PersonClassificationId Capacity
----------------------
1 2
2 2
3 2
I need to select such TypeId that in the entire TypeTable table do not have at least one PersonClassificationID specified in PersonTable.
So, if PersonTable has 1, 2, 3, then TypeId = 2 should be selected, because there is no record in TypeTable:
TypeId PersonClassificationId
----------------------
2 3
How can I do that?
It is undesirable to use cursors : )
I think that you can do what you want by generating all possible combinations of types and classifications, and then filter on those that do not exist in the mapping table:
select t.TypeId, pc.PersonClassificationId
from (select distinct TypeId from TypeTable) t
cross join PersonClassificationTable p
where not exists (
select 1
from TypeTable t1
where t1.TypeId = t.TypeId and t1.PersonClassificationId = p.PersonClassificationId
)

Left joining multiple tables with select statements and aliases

I'm doing a db2 stored procedure where I'm left joining multiple tables into a new table and adding tablename as a prefix to all column names. Running into a lot of obstacles and I could use some help structuring this statement. See an example of what I'm trying to do below. Does anyone have suggestions on how to do this?
CREATE TABLE <new_table> AS
SELECT * FROM (
SELECT t1.<column1> AS t1.<table1>_<column1>, t1.<column2> AS t1.<table1>_<column2> , ... FROM <table1> t1
LEFT JOIN
(SELECT <column1> AS <table2>_<column1>, <column2> AS <table2>_<column2> , ... FROM <table2>) t2
ON t2.<table2>_<column2> = t1.<table1>_<column1>
LEFT JOIN
(SELECT <column1> AS <table3>_<column1>, <column2> AS <table3>_<column2> , ... FROM <table3>) t3
ON t2.<table2>_<column1> = t3.<table3>_<column1>
);
When your column names include periods or special characters you will always need to double-quote the column names when they are used in SQL or DDL. This is sometimes painful.
The example below is for Db2-LUW V11.1.3.3 or higher:
create table thom.o1 (a integer, b integer);
create table thom.o2 (a integer, b integer);
create table thom.o3 (a integer, b integer);
insert into thom.o1(a,b) values(1,2);
insert into thom.o2(a,b) values(1,4),(1,3),(1,5),(2,9);
insert into thom.o3(a,b) values(1,6),(1,7),(1,8),(3,10);
create table thom.new_tab as (
select t1.a as "t1.o1.a"
,t1.b as "t1.o1.b"
,t2.a as "t2.o2.a"
,t2.b as "t2.o2.b"
,t3.a as "t3.o3.a"
,t3.b as "t3.o3.b"
from thom.o1 t1
left join thom.o2 t2
on t1.a = t2.a
left join thom.o3 t3
on t2.a = t3.a
) with data
;
describe table thom.new_tab;
Data type Column
Column name schema Data type name Length Scale Nulls
------------------------------- --------- ------------------- ---------- ----- ------
t1.o1.a SYSIBM INTEGER 4 0 Yes
t1.o1.b SYSIBM INTEGER 4 0 Yes
t2.o2.a SYSIBM INTEGER 4 0 Yes
t2.o2.b SYSIBM INTEGER 4 0 Yes
t3.o3.a SYSIBM INTEGER 4 0 Yes
t3.o3.b SYSIBM INTEGER 4 0 Yes
6 record(s) selected.
select * from thom.new_tab ;
select * from thom.new_tab
t1.o1.a t1.o1.b t2.o2.a t2.o2.b t3.o3.a t3.o3.b
----------- ----------- ----------- ----------- ----------- -----------
1 2 1 4 1 6
1 2 1 5 1 6
1 2 1 3 1 6
1 2 1 4 1 7
1 2 1 5 1 7
1 2 1 3 1 7
1 2 1 4 1 8
1 2 1 5 1 8
1 2 1 3 1 8
9 record(s) selected.

Pairs with no duplicates grouped together

I have a table
ID GROUPID NAME
== ======= ========
1 100 A
2 100 B
3 200 C
4 200 D
5 300 E
6 100 F
I would like to create a table containing the permutation pairs within a group without any pairs that are the same on both first and second that looks like this:
PAIRID FIRST SECOND
====== ===== ======
1 1 2
2 1 6
3 2 1
4 2 6
5 3 4
6 4 3
7 6 1
8 6 2
I would like to do it in PL/SQL or straight SQL inserts if possible. I did this through Java already using a recursive function to go through the permutations.
You could self join the table:
SELECT ROW_NUMBER() OVER (ORDER BY a.id, b.id) AS pairid,
a.id AS FIRST, b.id AS second
FROM mytable a
JOIN mytable b ON a.groupid = b.groupid AND a.id <> b.id
ORDER BY 1 ASC;

SQL Inner Join and Partitioning To obtain RowNumbers when matching

I have 2 tables. The first table 'a' the second 'b'.
I am writing a query that grabs every row in table a (there is 33 rows defined) and inner joins table b where the EnclLocation or the BackPanLoc match the Workcell in table A.
I only want a row from table B where they match based off BackPan and EnclLocation but they are not the same records. table b has a few rows of data that is assigned to the same workcell as table a. I am just trying to retrieve those additional rows and partition it.
I attached table a and table b. I also attached the desired results for this query with respect to Workcell 10 only as an example... As you can see, table B has 4 records that has either the EnclLocation or the BackPanLoc = 10. But my results only show the same DelvNumber 4 times. any help is most appreicated.
Table a
Table b
Incorrect Results
Desired Results (showing only Workcell 10 as an example)
workcell DelvNumber RowNum
1 447910-02 1
2 445710-01 1
2 445710-01 2
3 444291-01 1
3 444291-01 2
4 447910-03 1
4 447910-03 2
5 648020-01 1
6 647800-02 1
7 646920-01 1
7 646920-01 2
8 644830-4-8 1
8 644830-4-8 2
9 443990-01 1
10 645960-01-03 1
10 445710-11 2
10 445710-02 3
10 445710-09 4
Code Used
WITH ss
AS (SELECT a.*,
Row_number()
OVER(
partition BY a.workcell
ORDER BY a.workcell) AS rownum
FROM nwcurrent a
INNER JOIN nwdeliverables b
ON b.encllocation = a.workcell
OR b.backpanloc = a.workcell
WHERE ( b.status < 9
AND ( b.encllocation <> 0
OR b.backpanloc <> 0 )
OR a.delvnumber = '123' ))
SELECT *
FROM ss
copy and paste format
1 447910-02 1
2 445710-01 1
2 445710-01 2
3 444291-01 1
3 444291-01 2
4 447910-03 1
4 447910-03 2
5 648020-01 1
6 647800-02 1
7 646920-01 1
7 646920-01 2
8 644830-4-8 1
8 644830-4-8 2
9 443990-01 1
10 645960-01-03 1
10 445710-11 2
10 445710-02 3
10 445710-09 4
SQLFiddle
http://sqlfiddle.com/#!3/a8682/4
A new try...
SELECT a.workcell
,a.DelvNumber AS A_DelvNumber
,b.DelvNumber AS B_DelvNumber
,CASE WHEN a.DelvNumber<>b.DelvNumber THEN b.DelvNumber ELSE a.DelvNumber END AS DelvNumber_Resolved
,Row_number() OVER(partition BY a.workcell ORDER BY a.workcell) AS rownum
FROM NWCurrent a
INNER JOIN NWDeliverables AS b ON b.EnclLocation=a.WorkCell OR b.BackPanLoc=a.WorkCell
WHERE (b.status <9 AND (b.EnclLocation<>0 OR b.BackPanLoc<>0)OR a.DelvNumber='123')

Updating column based on another column's value

How do i update table structured like this:
id[pkey] | parent_id | position
1 1
2 1
3 1
4 1
5 1
6 2
7 2
8 2
9 2
10 3
11 3
12 3
...and so on
to achieve this result:
id[pkey] | parent_id | position
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
6 2 1
7 2 2
8 2 3
9 2 4
10 3 1
11 3 2
12 3 3
...and so on
I was thinking about somehow mixing
SELECT DISTINCT parent_id FROM cats AS t;
with
CREATE SEQUENCE dpos;
UPDATE cats t1 SET position = nextval('dpos') WHERE t.parent_id = t1.parent_id;
DROP SEQUENCE dpos;
although im not really experienced with postgres, and not sure how to use some kind of FOREACH. I appreciate any help
You can get the incremental number using row_number(). The question is how to assign it to a particular row. Here is one method using a join:
update cats
set position = c2.newpos
from (select c2.*, c2.ctid as c_ctid,
row_number() over (partition by c2.parent_id order by NULL) as seqnum
from cats c2
) c2
where cats.parent_id = c2.parent_id and cats.ctid = c2.c_ctid;
Use row_number function
select parent_id,
row_number() over (partition by parent_id order by parent_id) as position_id from table
Try this:
UPDATE table_name set table_name.dataID = v_table_name.rn
FROM
(
SELECT row_number() over (partition by your_primaryKey order by your_primaryKey) AS rn, id
FROM table_name
) AS v_table_name
WHERE v_table_name.your_primaryKey = v_table_name.your_primaryKey;