I need to create a temp table with the data in table below in Netezza. The typical way I would create a temp table in Netezza is via
CREATE TEMP TABLE temp_table1 AS
(
-- statement to fill the data
) DISTRIBUTE ON RANDOM;
How do I go about constructing the statement to be used inside so that the data below is available in the temp table ?
+---------+----------+
| bin_val | bin_cnt |
+---------+----------+
| 0 | 2 |
| 4 | 10 |
| 8 | 15 |
| 12 | 12 |
| 16 | 6 |
| 20 | 1 |
+---------+----------+
A PostgreSQL solution would also be helpful.
Is this what you want?
select v.*
from (values (0, 2), (4, 10), (8, 15), (12, 12), (16, 6), (20, 1)
) v(bin_val, bin_cnt)
Here is a SQL Fiddle.
This will probably not work in Netezza, because it uses a very old version of Postgres. Instead, I think you can do:
select 0 as bin_val, 2 as bin_cnt union all
select 4, 10 union all
select 8, 15 union all
select 12, 12 union all
select 16, 6 union all
select 20, 1
CREATE TEMPORARY TABLE MY_TABLE AS
SELECT
A,
B,
C
FROM
DB1.TABLE1
WHERE A NOTNULL
LIMIT 100;
------ DROP TABLE MY_TABLE
Related
There is a lot of information online to go from flattened data to arrays or structs, but I need to do the opposite and I am having a hard time archiving it. I am using Google BigQuery.
I have something like:
| Id | Value1 | Value2 |
| 1 | 1 | 2 |
| 1 | 3 | 4 |
| 2 | 5 | 6 |
| 2 | 7 | 8 |
I would like to get for the example above:
1, [(1, 2), (3, 4)]
2, [(5, 6), (7, 8)]
If I try to put an array in the select with a group by it is not a valid statement
For example:
SELECT Id, [ STRUCT(Value1, Value2) ] as Value
FROM `table.dataset`
GROUP BY Id
Which returns:
1, (1, 2)
1, (3, 4)
2, (5, 6)
2, (7, 8)
Which is not what I am looking for. The structure I got is: Id, Value.Value1, Value.Value2 and I want Id, [ Value(V1, V2), Value(V1, V2), ... ]
You can do that with SELECT Id, ARRAY_AGG(STRUCT(Value1, Value2)) ... GROUP BY Id
Below is for BigQuery Standard SQL
#standardSQL
select id, array_agg((select as struct t.* except(id))) as `value`
from `project.dataset.table` t
group by id
If to apply to sample data in your question - output is
in MySQL, I am trying to select one row for each "foreign_id". It must be the row with the highest value in column "time" (which is of type DATETIME). Can you help me how the SQL SELECT statement must look like? Thank you!
This would be really great! I am already trying for hours to find a solution :(
This is my table:
primary_id | foreign_id | name | time
----------------------------------------------------
1 | 3 | a | 2017-05-18 01:02:03
2 | 3 | b | 2017-05-19 01:02:03
3 | 3 | c | 2017-05-20 01:02:03
4 | 5 | d | 2017-07-18 01:02:03
5 | 5 | e | 2017-07-20 01:02:03
6 | 5 | f | 2017-07-18 01:02:03
And this is what the result should look like:
primary_id | foreign_id | name | time
----------------------------------------------------
3 | 3 | c | 2017-05-20 01:02:03
5 | 5 | e | 2017-07-20 01:02:03
I tried to order the intermediate result by time (descending) and then to select only the first row by using LIMIT 1. But like this I cannot get one row for each foreign_id.
Another try was to first order the intermediate result by time (descending) and then to GROUP BY foreign_id. But the GROUP BY statement seems to be executed before the ORDER BY statement (I received the rows with primary_id 1 and 4 as a result, not 3 and 5).
Try this
SELECT DISTINCT *
From my_table A
INNER JOIN (SELECT foreign_id, Max(time) AS time FROM my_table GROUP BY foreign_id) B
ON A.foreign_id = B.foreign_id AND A.time = B.time
Just add some data sample to analyze special case
CREATE TABLE Table1
(`primary_id` int, `foreign_id` int, `name` varchar(1), `time` datetime)
;
INSERT INTO Table1
(`primary_id`, `foreign_id`, `name`, `time`)
VALUES
(1, 3, 'a', '2017-05-18 01:02:03'),
(2, 3, 'b', '2017-05-19 01:02:03'),
(3, 3, 'c', '2017-05-20 01:02:03'),
(7, 3, 'H', '2017-05-20 01:02:03'),
(4, 5, 'd', '2017-07-18 01:02:03'),
(5, 5, 'e', '2017-07-20 01:02:03'),
(6, 5, 'f', '2017-07-18 01:02:03')
;
http://sqlfiddle.com/#!9/38947b/6
select d.primary_id, d.foreign_id, c.name, d.time
from table1 c inner join (
select max(b.primary_id) primary_id, a.foreign_id, a.time
from table1 b inner join
( select foreign_id, max(time) time
from table1
group by foreign_id) a
on a.foreign_id = b.foreign_id and a.time=b.time
group by a.foreign_id, a.time ) d
on c.primary_id=d.primary_id
In days gone by you would code this as a correlated subquery:
SELECT *
FROM Table1 o
WHERE primary_id = (
SELECT min (m.primary_id) FROM Table1 m
WHERE m.time= (
SELECT max (i.time) FROM Table1 i
WHERE o.foreign_id=i.foreign_id
)
)
The extra subquery handles the case of duplicate foreign_id & time values. If you were sure that time was unique for each foreign_id you could omit the middle subquery.
I have table in my database that goes like this:
ID | VARIANT | SIFRANT | VALUE
When I call
SELECT * FROM example_table
I get each row on its own. But records in my database can have the same VARIANT. And I'd like to output those records them in the same row.
for example if I have
ID | VARIANT | SIFRANT | VALUE
1 | 3 | 5 | 50
2 | 3 | 6 | 49
3 | 3 | 1 | 68
I'd like the output to be
VARIANT | VALUES_5 | VALUES_6 | VALUES_1
3 | 50 | 49 | 68
EDIT: I found the solution using PIVOT, the code goes like this:
select *
from (
select variant, VALUE, SIFRANT
from example_table
)
pivot
(
max(VALUE)
for SIFRANT
in ('1','2','3','4','5','6','7','8','9','10')
)
It seems that you only need an aggregation on your data:
with test(ID, VARIANT, SIFRANT, VALUE) as
(
select 1, 3, 5, 50 from dual union all
select 2, 3, 6, 49 from dual union all
select 3, 3, 1, 68 from dual
)
select variant, listagg (value, ' ') within group ( order by id)
from test
group by variant
I have 3 tables:
SELECT id, letter
FROM As
+--------+--------+
| id | letter |
+--------+--------+
| 1 | A |
| 2 | B |
+--------+--------+
SELECT id, letter
FROM Xs
+--------+------------+
| id | letter |
+--------+------------+
| 1 | X |
| 2 | Y |
| 3 | Z |
+--------+------------+
SELECT id, As_id, Xs_id
FROM A_X
+--------+-------+-------+
| id | As_id | Xs_id |
+--------+-------+-------+
| 9 | 1 | 1 |
| 10 | 1 | 2 |
| 11 | 2 | 3 |
| 12 | 1 | 2 |
| 13 | 2 | 3 |
| 14 | 1 | 1 |
+--------+-------+-------+
I can count all As and Bs with group by. But I want to count As and Bs based on X,Y and Z. What I want to get is below:
+-------+
| X,Y,Z |
+-------+
| 2,2,0 |
| 0,0,2 |
+-------+
X,Y,Z
A 2,2,0
B 0,0,2
What is the best way to do this at MSSQL? Is it an efficent way to use foreach for example?
edit: It is not a duplicate because I just wanted to know the efficent way not any way.
For what you're trying to do without knowing what is inefficient with your current code (because none was provided), a Pivot is best. There are a million resources online and here in the stack overflow Q/A forums to find what you need. This is probably the simplest explanation of a Pivot which I frequently need to remind myself of the complicated syntax of a pivot.
To specifically answer your question, this is the code that shows how the link above applies to your question
First Tables needed to be created
DECLARE #AS AS TABLE (ID INT, LETTER VARCHAR(1))
DECLARE #XS AS TABLE (ID INT, LETTER VARCHAR(1))
DECLARE #XA AS TABLE (ID INT, AsID INT, XsID INT)
Values were added to the tables
INSERT INTO #AS (ID, Letter)
SELECT 1,'A'
UNION
SELECT 2,'B'
INSERT INTO #XS (ID, Letter)
SELECT 1,'X'
UNION
SELECT 2,'Y'
UNION
SELECT 3,'Z'
INSERT INTO #XA (ID, ASID, XSID)
SELECT 9,1,1
UNION
SELECT 10,1,2
UNION
SELECT 11,2,3
UNION
SELECT 12,1,2
UNION
SELECT 13,2,3
UNION
SELECT 14,1,1
Then the query which does the pivot is constructed:
SELECT LetterA, [X],[Y],[Z]
FROM (SELECT A.LETTER AS LetterA
,B.LETTER AS LetterX
,C.ID
FROM #XA C
JOIN #AS A
ON A.ID = C.ASID
JOIN #XS B
ON B.ID = C.XSID
) Src
PIVOT (COUNT(ID)
FOR LetterX IN ([X],[Y],[Z])
) AS PVT
When executed, your results are as follows:
Letter X Y Z
A 2 2 0
B 0 0 2
As i said in comment ... just join and do simple pivot
if object_id('tempdb..#AAs') is not null drop table #AAs
create table #AAs(id int, letter nvarchar(5))
if object_id('tempdb..#XXs') is not null drop table #XXs
create table #XXs(id int, letter nvarchar(5))
if object_id('tempdb..#A_X') is not null drop table #A_X
create table #A_X(id int, AAs int, XXs int)
insert into #AAs (id, letter) values (1, 'A'), (2, 'B')
insert into #XXs (id, letter) values (1, 'X'), (2, 'Y'), (3, 'Z')
insert into #A_X (id, AAs, XXs)
values (9, 1, 1),
(10, 1, 2),
(11, 2, 3),
(12, 1, 2),
(13, 2, 3),
(14, 1, 1)
select LetterA,
ISNULL([X], 0) [X],
ISNULL([Y], 0) [Y],
ISNULL([Z], 0) [Z]
from (
select distinct a.letter [LetterA], x.letter [LetterX],
count(*) over (partition by a.letter, x.letter order by a.letter) [Counted]
from #A_X ax
join #AAs A on ax.AAs = A.ID
join #XXs X on ax.XXs = X.ID
)src
PIVOT
(
MAX ([Counted]) for LetterX in ([X], [Y], [Z])
) piv
You get result as you asked for
LetterA X Y Z
A 2 2 0
B 0 0 2
I have a table like this:
Id Num Some text
--------------------
1 1 ""
2 1 ""
3 2 ""
4 2 ""
5 2 ""
6 2 ""
7 3 ""
What I want is a query to select the first ten distinct nums, so if I want to get the two first nums I'll get the first six rows. I'm using MariaDB.
Try this approach:
select *
from Table1 as T1
join (
select distinct num
from Table1
order by num
limit 2 ) as T2
on T1.num = T2.num
;
In a fiddle here: http://sqlfiddle.com/#!9/1468ad/5
In MySQL you can use LIMIT. The caveat is that LIMIT is not directly supported in the IN sub-queries and therefore you must use a sub-query inside a IN sub-query:
SQL Fiddle
MySQL 5.6 Schema Setup:
CREATE TABLE Table1
(`Id` int, `Num` int, `Some text` varchar(2))
;
INSERT INTO Table1
(`Id`, `Num`, `Some text`)
VALUES
(1, 1, '""'),
(2, 1, '""'),
(3, 2, '""'),
(4, 2, '""'),
(5, 2, '""'),
(6, 2, '""'),
(7, 3, '""')
;
Query 1:
select * from Table1
where Num in (select Num FROM(select distinct Num from Table1 order by Num limit 2)a)
Results:
| Id | Num | Some text |
|----|-----|-----------|
| 1 | 1 | "" |
| 2 | 1 | "" |
| 3 | 2 | "" |
| 4 | 2 | "" |
| 5 | 2 | "" |
| 6 | 2 | "" |