SQL How to return a result set that will combine multiple rows into one row - sql

I am trying to get one row returned for each store number and per date that includes all values from the RecordTypeA column for that date.
The table I am using is created with a column named "RecordTypeA", it is a bit data type with (1 and 0) entries. 1 equals Type A and 0 equals Type B.
What I am trying to do is show the value of the RecordTypeA column for the store if there are entries of 1 and / or 0 on the same date on the same row.
Scenario 1 (One row returns for the store for the date): RecordTypeA column value = '1'
There is one row in the table for the store and date and the RecordTypeA column = '1' :
Scenario 2 (Two Rows return for the store for the same date):
Row One - RecordTypeA = '1'
Row Two - RecordTypeA = '0' (The column is still named RecordTypeA, but value '0' means something different so I want to create a column name?)
Scenario 3 (One row returns for the store for the date):
RecordTypeA column value = '0'
There is one row in the table for the store and date and the RecordTypeA column = '0' :
My issue is that I am getting multiple rows returned when the store has a RecordtypeA = 0 and a RecordtypeA = 1 row. Which I need to return on the same row. (Create columns that hold both 1 and 0 or Null.
What I am getting is
StoreID Date RecordTypeA
1234 2020-01-04 0
1234 2020-01-05 0
1234 2020-01-05 1
Needed:
StoreID Date RecordTypeA RecordTypeB
1234 2020-01-04 0 NULL
1234 2020-01-05 0 1
I have tried adding in case statements but I have not been able to get the one row as needed. Also, searched and tried PIVOT statements (I don't truly understand PIVOTs) but I get an error on the RecordTypeA Bit type.
Case when s.RecordTypeA = '1' Then 'TypeA' Else 'Null' End as Type
Case when s.RecordTypeA = '0' Then 'TypeB' Else 'Null' End as Type
SELECT r.StoreID,
r.CreatedDate,
s.RecordTypeA
From Request r
Inner Join Stores s on r.id = s.id
Group by r.StoreID,
r.CreatedDate,
s.RecordTypeA

Welcome to stack overflow community!
Have you tried to construct 3 queries and use UNION ALL statement?
You can create a query for StoreID, Date, RecordTypeA, TypeB and Typec.
For example:
SELECT CONCAT(r.StoreID, r.CreatedDate, s.RecordTypeA) AS DATA, 'A' AS TYPE
FROM YOURDATABASE.YOURTABLE
WHERE (A CRITERIA FOR TYPE A)
UNION ALL
SELECT CONCAT(r.StoreID, r.CreatedDate, s.RecordTypeA) AS DATA, 'B' AS TYPE
FROM YOURDATABASE.YOURTABLE
WHERE (A CRITERIA FOR TYPE B)
UNION ALL
...
I use the same alias on the example because with union all, all the queries must have the same columns, so you can use a CONCAT to put all your data from the different queries in one column, the column "TYPE" is for the difference the queries at the result.
Even if you not use concat you can return the columns different but all the queries must have the same column count on the select.
With multiple queries, you can define de criteria you want for type A, B, C through Z but have all of them at one result.
Important: Union all statements are somehow heavy for performance, so have it in mind.

Related

How to set flag based on values in previous columns in same table ? (Oracle)

I'm creating a new table and carrying over several columns from a previous table. One of the new fields that I need to create is a flag that will have values 0 or 1 and value needs to be determined based on 6 previous fields in the table.
The 6 previous columns have preexisting values of 0 or 1 stored for each one. This new field needs to check whether any of the 6 columns have 1 and if so set the flag to 0. If there is 0 in all 6 fields then set itself to 1.
Hopefully this makes sense. How can I get this done in oracle? I assume a case statement and some sort of forloop?
You can use greatest() function: GREATEST
create table t_new
as
select
case when greatest(c1,c2,c3,c4,c5,c6)=1 -- at least one of them contains 1
then 0
else 1
end c_new
from t_old;
Or even shorter:
create table t_new
as
select
1-greatest(c1,c2,c3,c4,c5,c6) as c_new
from t_old;
In case of greatest = 1, (1-1)=0, otherwise (1-0)=1
You can use a virtual column with a case expression; something like:
flag number generated always as (
case when val_1 + val_2 + val_3 + val_4 + val_5 + val_6 = 0 then 1 else 0 end
) virtual
db<>fiddle
or the same thing with greatest() as #Sayan suggested.
Using a virtual column means the flag will be right for newly-inserted rows, and if any of the other values are updated; you won't have to recalculate or update the flag column manually.
I've assumed the other six columns can't be null and are constrained to only be 0 or 1, as the question suggests. If they can be null you can add nvl() or coalesce() to each term in the calculation.

NULL behavior with Comoperator like ALL in Oracle SQL

SELECT * FROM hr.NullValueCheck
ID Name
1 abc
2 abc
3 bcd
4 cde
https://oracle-base.com/articles/misc/all-any-some-comparison-conditions-in-sql
Query 1 :
SELECT *
FROM hr.NullValueCheck
where id > All (SELECT NULL FROM DUAL )
Nothing is coming.
But for below quesry. All records are coming while subquesry is returning is NULL same as like above query (SELECT NULL FROM DUAL )
Query 2:
SELECT *
FROM hr.NullValueCheck
where id > All (SELECT id from hr.NullValueCheck where id = 5)
Please explain me why Query 1 is returning No Records but Query 2 is returning all records.
As per my knowledge Query 1 should also return all records.
NULL is different from an empty set.
The first example is saying: "select all rows where the id is greater than all values of NULL". Or more simply, "where id is greater than 'NULL'`.
In SQL, 'NULL' generally has the semantics of "not known". If you don't know the value, then you don't know if a given id is larger. Hence, no rows are returned.
In the second example, instead has an empty set for comparison. An empty set is not NULL. Obviously, any number is greater than all numbers in an empty set. Hence, all rows are returned.

Return 0 in Sheets Query if there is no data

I need some advice in google query language.
I want to count rows depending on date and a condition. But if the condition is not met, it should return 0.
What I'm trying to achieve:
Date Starts
05.09.2018 0
06.09.2018 3
07.09.2018 0
What I get:
Date Starts
06.09.2018 3
The query looks like =Query(Test!$A2:P; "select P, count(B) where (B contains 'starts') group by P label count(B) 'Starts'")
P contains ascending datevalues and B an event (like start in this case).
How can I force output a 0 for the dates with no entry containing "start"?
The main point is to get all needed data in one table in ascending order. But this is only working, if every day has an entry. If there is no entry for a day, the results for "start" do not match the datevalue in column A. 3 in column D would be in the first row of the table then.
I need it like this:
A B C D
Date Logins Sessions Starts
05.09.2018 1 2 0
06.09.2018 3 4 3
07.09.2018 4 5 0
Maybe this is easy to fix, but I don't see it.
Thanks in advance!
You can do some pre-processing before the query. Ex: check if column B contains 'start' with regexmatch and use a double unary (--) to force the boolean values into 1's and 0's. The use query to sum.
=Query(Arrayformula({--regexmatch(Test!$B2:B; "start")\ Test!$A2:P}); "select Col17, sum(Col1) where Col17 is not null group by Col17 label sum(Col1) 'Starts'")
Change ranges to suit.

Find certain values and show corresponding value from different field in SQL

So I found these 2 articles but they don't quite answer my question...
Find max value and show corresponding value from different field in SQL server
Find max value and show corresponding value from different field in MS Access
I have a table like this...
ID Type Date
1 Initial 1/5/15
1 Periodic 3/5/15
2 Initial 2/5/15
3 Initial 1/10/15
3 Periodic 3/6/15
4
5 Initial 3/8/15
I need to get all of the ID numbers that are "Periodic" or NULL and corresponding date. So I want a to get query results that looks like this...
ID Type Date
1 Periodic 3/5/15
3 Periodic 3/6/15
4
I've tried
select id, type, date1
from Table1 as t
where type in (select type
from Table1 as t2
where ((t2.type) Is Null) or "" or ("periodic"));
But this doesn't work... From what I've read about NULL you can't compare null values...
Why in SQL NULL can't match with NULL?
So I tried
SELECT id, type, date1
FROM Table1 AS t
WHERE type in (select type
from Table1 as t2
where ((t.Type)<>"Initial"));
But this doesn't give me the ID of 4...
Any suggestions?
Unless I'm missing something, you just want:
select id, type, date1
from Table1 as t
where (t.type Is Null) or (t.type = "") or (t.type = "periodic");
The or applies to boolean expressions, not to values being compared.

Compare two unrelated tables sql

We're dealing with geographic data with our Oracle database.
There's a function called ST_Insertects(x,y) which returns true if record x intersects y.
What we're trying to do is, compare each record of table A with all records of table B, and check two conditions
condition 1 : A.TIMEZONE = 1 (Timezone field is not unique)
condition 2 : B.TIMEZONE = 1
condition 3 : ST_Intersects(A.SHAPE, B.SHAPE) (Shape field is where the geographical information is stored)
The result we're looking for is records ONLY from the table A that satisfy all 3 conditions above
We tried this in a single select statement but it doesn't seem to make much sense logically
pseudo-code that demonstrates a cross-join:
select A.*
from
tbl1 A, tbl2 B
where
A.TIMEZONE = 1 and
B.TIMEZONE = 1 and
ST_Intersects(A.SHAPE, B.SHAPE)
if you get multiples, you can put a distinct and only select A.XXX columns
With a cross-join rows are matched like this
a.row1 - b.row1
a.row1 - b.row2
a.row1 - b.row3
a.row2 - b.row1
a.row2 - b.row2
a.row2 - b.row3
So if row 1 evaluates to true on multiple rows, then just add a distinct on a.Column1, etc.
If you want to use the return value from your function in an Oracle SQL statement, you will need to change the function to return 0 or 1 (or 'T'/'F' - some data type supported by Oracle Database, which does NOT support the Boolean data type).
Then you probably want something like
select <columns from A>
from A
where A.timezone = 1
and exists ( select *
from B
where B.timezone = 1
and ST_intersects(A.shape, B.shape) = 1
)