SQL - How to retrieve the correct number - sql

I have written a personal pseudocode to help others understand what I am trying to achieve. I am a beginner in SQL but I know all the basics, just not experienced enough with the possiblilities.
I tried using SELECT CASE but it doesn't achieve what I need.
Here is my sample data
CREATE TABLE Records
([ColA] INTEGER, [ColB] INTEGER, [ColTotal] INTEGER)
;
INSERT INTO Records
([ColA], [ColB] )
VALUES
('3', '4'),
('4', '2’),
('1', '2'),
('3', '5'),
('3', '1'),
('2', '2')
;
Here is my PSEUDOCODE (I found out after accepted answer that my logic in the psuedo was incorrect too. This has been fixed)
SELECT COL A, COL B, COL TOTAL
IF COL A >= COLB THEN
ADD COLB value to COL TOTAL
ELSE
USE Value from COLA and add to total
END IF
Here is my SQL
SELECT SUM(ColTotal)
FROM t
WHERE ColA >= ColB

Is this what you want?
select sum(case when a < b then a else b end) as total
from t;
Many databases support the least() function, which makes this simpler:
select sum(least(a, b)) as total
from t;

Related

Grouped IF statement in SQL

My data take this basic shape: (http://sqlfiddle.com/#!9/d4ae98/1)
CREATE TABLE Table1
(`ID` int, `Type` varchar(1));
INSERT INTO Table1
(`ID`, `Type`)
VALUES
(123, 'A'),
(123, 'B'),
(123, 'C'),
(456, 'A'),
(789, 'A'),
(789, 'B')
;
What I want is, a third column which is true/false for every row, based on whether that row's ID value has type='B' anywhere in the data. So the desired output would be:
ID Type V3
123 A t
123 B t
123 C t
456 A f
789 A t
789 B t
What is the best way to do this? (And, yes, I am aware that a scripting language like R or Python could easily do what I want here, but I want to use this output as a WITH clause in a larger SQL query.)
You can do this with a Case in the Select:
select *, CASE
WHEN id in (select id from table1 where type like '%B%') then 't'
ELSE 'f'
END V3
from table1;
Fiddle link: http://sqlfiddle.com/#!9/e47bc37/1
May a solution like this one can help you:
with Table2 as (
select * from table1 where type ='B'
)
select t1.*, case t2.type when 'B' then 't' else 'f' end v3 from table1 t1 left
outer join table2 t2 on t1.id = t2.id ;

SQL WHERE clause that can exclude by integer but also include according to a date

I want to be able to exclude 2 of the 5 possible integers in RowA, but include any rows before 1/1/2021 only. I've tried a HAVING clause with the date where I GROUP BY a created_date, but that returned an error. So this is my entire clause currently, I get a "this query returned 0 results" when I know there are results. I've tried the RowA NOT IN ('1', '2') by itself in the WHERE clause (WHERE RowA NOT IN ('1', '2')) and had results returned. Also tried just having the WHERE created_date <= 1/1/2021 and had results returned. Edited to include a picture showing sample data and desired results. Here's the formula as is, which returns 0 results:
SELECT *
FROM Table1
WHERE created_date <= 1/1/2021
AND RowA NOT IN ('1', '2')
ORDER BY created_date
You can try the below -
select * from
(
SELECT * FROM Table1 WHERE created_date<'1/1/2021'
)A where RowA NOT IN (1, 2)
I think your SQL code shall work in BigQuery and give you the correct answer.
below I reproduced the expected result using your SQL code (with minor syntax revision)
WITH Table1 AS
(
SELECT t.*
FROM UNNEST(
ARRAY<STRUCT< created_date Date, RowA INT64 >>
[("2021-1-7", 1),
("2020-12-29", 2),
("2020-11-30", 3),
("2020-3-5", 2),
("2021-2-2", 4),
("2020-9-7", 5),
("2021-1-30", 1)
]
) as t
)
SELECT * FROM Table1
WHERE created_date <= "2021-1-1"
AND RowA NOT IN (1, 2) ORDER BY created_date

SQL count multiple cells as combination

I have the following SQL table which shows case number and their value, the case number always appear 2 cases in a group, I want to count how many the combinations with same case number appearing in the table. Be ware the order could be different, see case A and C, both of them should be count as the same combination.
case value
A 1992
A 1956
B 2000
B 2001
C 1956
C 1992
The goal is to get the total number of each combination, so the output format doesn't matter. One of expected result:
Seq value frequency
1 1992 2
1 1956 2
2 2000 1
2 2001 1
What about if there are 3 cases as a combination?
This works with any number of values for any case. It only increment frequency count when cases have the same number of values and each one have a match, no matter in which order.
CREATE TABLE #Table1
([Case] varchar(1), [Value] int)
;
INSERT INTO #Table1
([Case], [Value])
VALUES
('A', 1992), ('A', 1956), ('A', 1997), ('B', 2000), ('B', 2001), ('C', 1956),
('C', 1992), ('C', 1997), /*('C',1993),*/ ('D', 2005), ('D', 2008), ('E', 1956),
('E', 1992) , ('F', 1956), ('F', 1992), ('G', 1956), ('G', 1992) ;
--Query
select min(a.[Case]) [Case], [Values], count(*) frequency
from (
SELECT t.[Case],
stuff(
(
select ',' + cast (t1.[Value] as varchar(20))
from #table1 t1
where t1.[Case] = t.[Case]
order by t1.[Value]
for xml path('')
),1,1,'') [Values]
FROM #table1 t
GROUP BY t.[Case]
)a
group by [Values]
order by [Case]
Result whith values sorted in ascending order
Case Values frequency
A 1956,1992,1997 2
B 2000,2001 1
D 2005,2008 1
E 1956,1992 3
Data sample, SQL Server 2014
CREATE TABLE Table1
([case] varchar(1), [value] int)
;
INSERT INTO Table1
([case], [value])
VALUES
('A', 1992),
('A', 1956),
('B', 2000),
('B', 2001),
('C', 1956),
('C', 1992)
;
Query
select dense_rank() over (ORDER BY min(a.[case])) seq, a.value, count(*) freq
from table1 a left join table1 b
on a.value=b.value and a.[case]<>b.[case]
group by a.value
order by a.value
http://sqlfiddle.com/#!6/40a87/3
This is not exactly as you post expected results, but respond on what you just request in the previous comment.
select min, max, count (*) freq
from (
select a.[case] [case], min(a.value) min, max(a.value) max
from table1 a
group by a.[case]) b
group by min, max
order by min, max
http://sqlfiddle.com/#!6/40a87/18

Select all rows where two columns contain a combination of values

Here's my schema:
CREATE TABLE T (A CHAR(1), B CHAR(1));
INSERT INTO T (A, B) VALUES('1', '1');
INSERT INTO T (A, B) VALUES('2', '2');
INSERT INTO T (A, B) VALUES('1', '2');
I wan't to select rows where columns A and B contain a combination of values. For example, lets say I want to find combinations A=1,B=1, and A=2,B=2, and nothing else. If it were a single value, I could use the IN statement, but when I try this:
SELECT * FROM T WHERE A IN ('1', '2') AND B IN ('1', '2')
I get back all three rows.
How can I match a combination of values?
You can check this query :
SELECT * FROM T WHERE (A,B) IN (('1', '1'),('2', '2'));
see given link below
Click here
Is this what you're looking for using OR with parentheses?
select *
from T
where ( A = '1' AND B = '1' ) OR ( A = '2' AND B = '2' )
SQL Fiddle Demo
you can use something like below sql
SELECT * FROM T WHERE (A == B) AND A IN ('1', '2');

PostgreSQL: How to search a list of strings as a table?

It's been a while since I've had to do any db work, so I'm not really sure how to ask this and I know I've done it in the past.
How do you create a temporary table out of a list of strings (not using CREATE TEMPORARY TABLE)? So, if you have something like :
'1', 'a', 'A'
'2', 'b', 'B'
'3', 'c', 'C'
SELECT field2
FROM { {'1','a','A'}, {'2','b','B'}, {'3','c','C'} }
AS fooarray(field1,field2,field3)
WHERE field1 = '2'
-- should return 'b'
Hint: It's similar to...
SELECT * FROM unnest(array[...]);
You don't need to mess around with arrays at all, you can build the table in-place using VALUES:
7.7. VALUES Lists
VALUES provides a way to generate a "constant table" that can be used in a query without having to actually create and populate a table on-disk.
See also VALUES.
So you can do things like this:
=> select *
from (
values ('1', 'a', 'A'),
('2', 'b', 'B'),
('3', 'c', 'C')
) as t(id, c1, c2)
where id = '2';
id | c1 | c2
----+----+----
2 | b | B
(1 row)
Don't forget to give your VALUES an alias complete with column names (t(id, c1, c2)) so that everything has a name.