I have table as below. If I need to create another table as shown in the output, how can I do it?
CREATE TABLE TestTable
(JobID int, isAllowType1 bit, value1 int, isAllowType2 bit, value2 int)
;
INSERT INTO TestTable
(JobID, isAllowType1, value1, isAllowType2, value2)
VALUES
(1, 1, 11, 0, 111),
(2, 0, 22, 1, 222),
(3, 1, 33, 0, 333)
;
--output
JOBID isAllow Value Type
1 1 11 Type1
1 0 111 Type2
2 0 22 Type1
2 1 222 Type2
3 1 33 Type1
3 0 333 Type2
You can use the query the type1 and type2 records separately, and use the union all operator to combine the results:
SELECT jobid, isAllowType1 AS isAllow, value1 AS value, 'Type1' AS type
FROM testtable
UNION ALL
SELECT jobid, isAllowType1 AS isAllow, value1 AS value, 'Type2' AS type
FROM testtable
To add to Mureinik's answer, you can create a new table using result of a UNION ALL like so:
select *
into new_table
from (
select JobID,
isAllowType1 isAllowType,
value1 value,
'Type1' Type
from TestTable
union all
select JobID,
isAllowType2,
value2,
'Type2'
from TestTable
) t
Related
Using SQL Server
The output I want: For the same values in column ID1, if there is a “null” in column ‘Value’ than make it equal to minimum(value) of that ID1.
I previously had a question relating to the following, although have still been unable to solve this!
Table 1
ID1
ID2
Value
1
1
0.1
1
2
2
1
3
null
2
5
0.2
2
5
null
3
7
6
Output I want
ID1
ID2
Value
1
1
0.1
1
2
2
1
3
0.1
2
5
0.2
2
5
0.2
3
7
6
you can use min() with window function
select ID1, ID2,
[Value] = coalesce(Value,
min(Value) over (partition by ID1))
from yourTable
WITH minimumValues AS (SELECT ID1, MIN(value) as value FROM table GROUP BY ID1)
SELECT
ID1,
ID2,
COALESCE( table1.Value, minimumValues.value) AS value
FROM table INNER JOIN
MinimumValues ON MinimumValues.ID1 = table.ID1
You can try the below to get the desired output -
Sample Table:
CREATE TABLE SampleData (
ID1 INT,
ID2 INT,
Value FLOAT
);
Sample Data:
INSERT INTO SampleData
(ID1, ID2, Value)
VALUES
(1, 1, 0.1),
(1, 2, 2),
(1, 3, NULL),
(2, 5, 0.2),
(2, 5, NULL),
(3, 7, 6);
Query:
WITH cte AS (
SELECT ID1, MIN(Value) AS MinValue
FROM SampleData
WHERE Value IS NOT NULL
GROUP BY ID1
)
SELECT t.ID1, t.ID2, COALESCE(t.Value, cte.MinValue) AS Value
FROM SampleData t
JOIN cte ON t.ID1 = cte.ID1
Is there a way to get the value distribution for a field in SQL dynamically?
I have a table with 250 fields. I would like to get the value distribution for each of these fields:
field0
value0: 10
value1: 100
value2: 30
...
valueN: X
field1
value0: 2
value1: 124
value2: 8
...
valueN: Y
....
I know that with case + sum it is possible to generate this but then the possible values have to be put in the query in advance:
SELECT
, Sum( Case When field0 = value0 Then 1 Else 0 End ) As [0]
, Sum( Case When field0 = value1 Then 1 Else 0 End ) As [1]
, Sum( Case When field0 = value2 Then 1 Else 0 End ) As [2]
, Sum( Case When field0 = value3 Then 1 Else 0 End ) As [3]
, Sum( Case When field0 = valueN Then 1 Else 0 End ) As [4]
FROM table
Is there a way to do this dynamically?
There is an a way for rows result (not columns result ) using aggregation function eg: count
SELECT field0,
COUNT(*)
FROM table
GROUP BY field0
if you want a columns result as in your code . for some DB brand there are PIVOT functionatlities .
With Postgres you could do something like this:
select t.name as column_name,
sum(val::int) as sum
from data d, jsonb_each_text(to_jsonb(d) - 'id') as t(name, val)
group by t.name;
The - 'id' removes the id attribute from the generated JSON. Another option to only include certain columns in the aggregation is to add a where condition:
select column_name,
sum(val::int) as sum
from (
select t.name as column_name,
t.val
from data d, jsonb_each_text(to_jsonb(d)) as t(name, val)
) t
where column_name like 'col%'
group by column_name;
With the following sample table:
create table data
(
id serial primary key,
col1 int,
col2 int,
col3 int,
col4 int,
col5 int
);
insert into data (col1, col2, col3, col4, col5)
values
(1, 2, 3, 4, 5),
(6, 7, 8, 9, 10),
(11, 12, 13, 14, 15);
The query would return:
column_name | sum
------------+----
col1 | 18
col2 | 21
col5 | 30
col4 | 27
col3 | 24
I have a table that looks like
id cat data
--------------------
1 1 foo
2 1 bar
3 1 baz
4 2 some
5 2 random
6 3 Data 1
7 2 data
8 3 Data 2
9 3 Data 3
And I want the last 3 ids and data of each category in a single row like
cat id1 data1 id2 data2 id3 data3
-----------------------------------------------------
1 1 foo 2 bar 3 baz
2 4 some 5 random 7 data
3 6 Data 1 8 Data 2 9 Data 3
I already tried the following:
Get the data with the highest id for each cat:
SELECT id, data FROM tbl t1 WHERE EXISTS (
SELECT 1 FROM tbl t2 WHERE t1.cat = t2.cat
GROUP BY t2.cat HAVING MAX(t2.id) = t1.id
)
Get the data with the 2nd highest ids for each cat:
SELECT id, data FROM tbl t1 WHERE EXISTS (
SELECT 1 FROM tbl t2 WHERE t1.cat = t2.cat AND NOT EXISTS (
-- Not the highest value
SELECT 1 FROM tbl t3 WHERE t1.cat = t3.cat GROUP BY t3.cat
HAVING MAX(t3.id) = t2.id
) GROUP BY t2.cat HAVING MAX(t2.id) = t1.id
)
Get the data with the 3rd highest id for each cat:
SELECT id, data FROM tbl t1 WHERE EXISTS (
SELECT 1 FROM tbl t2 WHERE t1.cat = t2.cat AND NOT EXISTS (
-- id is not 2nd highest
SELECT 1 FROM tbl t3 WHERE t1.cat = t3.cat AND NOT EXISTS (
-- id is not the highest
SELECT 1 FROM tbl t4 WHERE t1.cat = t4.cat GROUP BY t4.cat
HAVING MAX(t4.id) = t3.id
) GROUP BY t3.cat HAVING MAX(t3.id) = t2.id
) AND NOT EXIST (
-- not the highest id
SELECT 1 FROM tbl t5 WHERE t1.cat = t5.cat GROUP BY t5.cat
HAVING MAX(t5.id) = t2.id
) GROUP BY t2.cat HAVING MAX(t2.id) = t1.id
)
And now, joining the entire thing. But I believe that there exists a better solution. What is it?
PS: I have to do it with Informix
Not my answer, a coworker of mine came up with this:
create temp table t(
id smallint,
cat smallint,
data char(10)
) with no log;
insert into t values (1, 1, "foo");
insert into t values (2, 1, "bar");
insert into t values (3, 1, "baz");
insert into t values (4, 2, "some");
insert into t values (5, 2, "random");
insert into t values (6, 3, "Data 1");
insert into t values (7, 2, "data");
insert into t values (8, 3, "Data 2");
insert into t values (9, 3, "Data 3");
insert into t values (10, 4, "some");
insert into t values (11, 4, "more");
insert into t values (12, 4, "random");
insert into t values (13, 4, "data");
insert into t values (14, 4, "for");
insert into t values (15, 4, "testing");
insert into t values (16, 5, "one");
select
cat,
max(case when cnt = 3 then id end) as id1,
max(case when cnt = 2 then id end) as id2,
max(case when cnt = 1 then id end) as id3,
max(case when cnt = 3 then data end) as data1,
max(case when cnt = 2 then data end) as data2,
max(case when cnt = 1 then data end) as data3
from
(
select
a.cat,
a.id,
a.data,
count(*) as cnt
from
t a,
t b
where
a.cat = b.cat and
a.id <= b.id
group by
a.id,
a.cat,
a.data
having
count(*) <= 3
)
group by
1
order by
1;
cat id1 id2 id3 data1 data2 data3
1 1 2 3 foo bar baz
2 4 5 7 some random data
3 6 8 9 Data 1 Data 2 Data 3
4 13 14 15 data for testing
5 16 one
If you using Informix 11.50 or above , there is an option where isn't perfect, but maybe can help. Check the select at end bellow.
They will return a multiset datatype with char() data type... where probably will create a difficult to read it, depending of the program language are you using.
Thanks to Fernando Nunes who suggest this SQL into IIUG forum
At this moment I don't see other alternative besides complex SQLs.
drop table teste;
create temp table teste ( id smallint, cat smallint, data char(10));
insert into teste values ( 1, 1, 'foo ' );
insert into teste values ( 2, 1, 'bar ' );
insert into teste values ( 3, 1, 'baz ' );
insert into teste values ( 4, 2, 'some ' );
insert into teste values ( 5, 2, 'random ' );
insert into teste values ( 6, 3, 'Data 1 ' );
insert into teste values ( 7, 2, 'data ' );
insert into teste values ( 8, 3, 'Data 2 ' );
insert into teste values ( 9, 3, 'Data 3 ' );
insert into teste values ( 10, 3, 'Data 4 ' );
select * from teste;
select ms.*
from
(
SELECT MULTISET( SELECT ITEM t.id || ',' || t.cat || ',' || t.data m1 FROM
teste t WHERE t.cat = tout.cat) FROM (SELECT unique cat from teste) tout
) msdrop table teste;
will return :
expression MULTISET{'1,1,foo ','2,1,bar ','3,1,baz '}
expression MULTISET{'4,2,some ','5,2,random ','7,2,data '}
expression MULTISET{'6,3,Data 1 ','8,3,Data 2 ','9,3,Data 3 '}
I have the following row from a table in MSSQL
Person | value1 | value2 | value3 | value4
John | 4 | 7 | 1 | 2
I want this row sorted according to the values as shown below.
Person | value2 | value1 | value4 | value3
John | 7 | 4 | 2 | 1
May be I'm asking a stupid question , I want the column names to be sorted according to the values in those column.
I know that this can be achieved using query
SELECT *
FROM tableName
ORDER BY value2, value1, value4, value3 DESC
But when I change the any column value, I have to change the query to get the result sorted.
Please help...
-- sample data
declare #t table
(
person varchar(50),
value1 int,
value2 int,
value3 int,
value4 int
)
insert into #t select 'John', 4, 7, 1, 2
insert into #t select 'Name1', 14, 7, 1, 16
insert into #t select 'Name2', 24, 8, 1, 2
-- query
select
person, v1 = [1], v2 = [2], v3 = [3], v4 = [4]
from
(
select person, rn = row_number() over(partition by person order by a desc), a
from #t t1
unpivot
(
a for b in (value1, value2, value3, value4)
) t2
) t1
pivot
(
max(a) for rn in ([1], [2], [3], [4])
) t2
unless I'm missing something, you should just append 'order by person, value2, value1, value4, value3' at the end of your select statement.
I think you want:
SELECT Person, Value2, Value1, Value4, Valuer
FROM YourTable
try this:
SELECT * FROM tableName ORDER BY value2, value1, value4, value3 DESC
Fiends Please help me with this ASAP. Really appreciate it thanks
I have really simple table. Which as three columns
Col A Col B Col C
(unique)nameA (UniqueID)1 (somenumber)10
(unique)nameB (UniqueID)2 (somenumber)20
(unique)nameC (UniqueID)3 (somenumber)30
(unique)nameD (UniqueID)4 (somenumber)10
(unique)nameE (UniqueID)5 (somenumber)50
(unique)nameF (UniqueID)6 (somenumber)35
(unique)nameG (UniqueID)7 (somenumber)50
(unique)nameH (UniqueID)8 (somenumber)10
(unique)nameI (UniqueID)9 (somenumber)25
As per my report requirement i need to combine Unique ID (1,2,3) Give it a Unique name ALFA and Sum the Col C values AND combine (4,5,6) Give it a Unique name BETA and Sum the Col C values for them
And keep other Unique ID, Unique Name and Their values in Col C as is
Order by values in Col C Desc and display TOP 30 results.
So Final result should look like this
Col A Col B Col C
BETA (unique ID 4,5,6) 95 --(10+50+35 from col C
ALFA (unique ID 1,2,3) 60 --(10+20+30 from col C above)
above)
(unique)nameG (UniqueID)7 (somenumber)50
(unique)nameI (UniqueID)9 (somenumber)25
(unique)nameH (UniqueID)8 (somenumber)10
ould something like this work?
declare #simpletable table( name varchar(50), uniqueid int, somenumber int)
insert into #simpletable
select 'a', 1, 10
union all
select 'b', 2, 20
union all
select 'c', 3, 30
union all
select 'd', 4, 10
union all
select 'e', 5, 50
union all
select 'f', 6, 35
union all
select 'g', 7, 50
union all
select 'h', 8, 10
union all
select 'i', 9, 25
select top 30 name,uniqueid,somenumber
from
(
select 'ALFA' as name, '1,2,3' as uniqueid, sum(somenumber) as somenumber
from #simpletable
where uniqueid between 1 and 3
union all
select 'BETA' as name, '4,5,6' as uniqueid, sum(somenumber) as somenumber
from #simpletable
where uniqueid between 4 and 6
union all
select name as name, cast(uniqueid as varchar(50)) as uniqueid, somenumber as somenumber
from #simpletable
where uniqueid > 6
) as x
order by somenumber desc