this is an initial table (this is just a part of a larger table where Article ID's can vary), database is MS Sql.
-----------------------------------
|ArticleID | GroupID |
-----------------------------------
| 1 | NULL |
-----------------------------------
| 2 | NULL |
-----------------------------------
| 3 | NULL |
-----------------------------------
| 4 | NULL |
-----------------------------------
Set of rows that should be entered for each ArticleID looks something like this:
------------------------
| GroupID |
------------------------
| A |
------------------------
| B |
------------------------
| C |
------------------------
| D |
------------------------
Result table should look something like this:
-----------------------------------
|ArticleID | GroupID |
-----------------------------------
| 1 | NULL |
-----------------------------------
| 1 | A |
-----------------------------------
| 1 | B |
-----------------------------------
| 1 | C |
-----------------------------------
| 1 | D |
-----------------------------------
| 2 | NULL |
-----------------------------------
| 2 | A |
-----------------------------------
| 2 | B |
-----------------------------------
| 2 | C |
-----------------------------------
| 2 | D |
-----------------------------------
| 3 | NULL |
-----------------------------------
| 3 | A |
-----------------------------------
| 3 | B |
-----------------------------------
| 3 | C |
-----------------------------------
| 3 | D |
-----------------------------------
| 4 | NULL |
-----------------------------------
| 4 | A |
-----------------------------------
| 4 | B |
-----------------------------------
| 4 | C |
-----------------------------------
| 4 | D |
-----------------------------------
Any suggestion how to insert it efficiently?
Thanks a lot for you suggestion.
Regards
This is a cross join between two sets.
with a as (
select * from(values (1),(2),(3),(4))v(ArticleId)
), g as (
select * from(values (null),('A'),('B'),('C'),('D'))v(GroupId)
)
select *
from a cross join g;
To insert into the original table you could do:
with g as (select * from(values('A'),('B'),('C'),('D'))v(GroupId))
insert into t
select t.ArticleId, g.GroupId
from t cross join g;
See Example Fiddle
I am trying to add a new column based on a condition in a group.
Could we do something like
BOOL() OVER (PARTITION BY id 'D' in val)
That is something like GROUP BY id and check if the value 'D" val column
Input:
-------------
| id | val |
------------|
| 1 | A |
| 1 | B |
| 1 | D |
| 2 | B |
| 2 | C |
| 2 | A |
Output
-------------------
| id | val | res |
------------|-----|
| 1 | A | 1 |
| 1 | B | 1 |
| 1 | D | 1 |
| 2 | B | 0 |
| 2 | C | 0 |
| 2 | A | 0 |
You didn't specify your DBMS, but in standard ANSI SQL, you can use a filter() clause:
count(*) filter (where val = 'D') over (partition by id) > 0
In Postgres, you can use bool_or() for this:
select t.*, bool_or(val = 'D') over(partition by id) res
from mytable t
Demo on DB Fiddle:
id | val | res
-: | :-- | :--
1 | A | t
1 | B | t
1 | D | t
2 | B | f
2 | C | f
2 | A | f
This gives you a boolean result. If you want it as an integer value instead, then:
(bool_or(val = 'D') over(partition by id))::int
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 table that I need has multiple rows and I to put them all into a new table.
All my rows need to be converted into one row.
+-------+-----------+-------+--------+
| ID | Name | Last | Gender |
+-------+-----------+-------+--------+
| 1 | Person1 | Last1 | M |
| 2 | Person2 | Last2 | F |
| 3 | Person3 | Last3 | M |
| 4 | Person4 | Last4 | F |
+-------+-----------+-------+--------+
I need to convert the above table to the below:
+-------+------------+------------+
| NewID | ColumnName | Value |
+-------+------------+------------+
| 1 | ID | 1 |
| 1 | Name | Person1 |
| 1 | Last | Last1 |
| 1 | Gender | M |
| 2 | ID | 2 |
| 2 | Name | Person2 |
| 2 | Last | Last2 |
| 2 | Gender | F |
| 3 | ID | 3 |
| 3 | Name | Person3 |
| 3 | Last | Last3 |
| 3 | Gender | M |
| 4 | ID | 4 |
| 4 | Name | Person4 |
| 4 | Last | Last4 |
| 4 | Gender | F |
| | | |
+-------+------------+------------+
The most general method is to use union all:
select 'id' as columnname, cast(id as varchar(255)) as value from t union all
select 'name', name as value from t union all
select 'last', last as value from t union all
select 'gender', gender as value from t;
This should work in basically any database, although the cast to a string might vary. Some databases offer other solutions that are more efficient.
Union happy solution.
select 'id' as columnname, id as value from table
union all
select 'name' as columnname, name as value from table
union all
.e
.t
.c