Lets say I have a table that has 50 Fields. 20 of those fields can contain the Value "YES" "NO" or "N/A". How do I query the number of "YES"s for a given row?
You write a long statement that adds up the values:
select ((case when value1 = 'Yes' then 1 else 0 end) +
(case when value2 = 'Yes' then 1 else 0 end) +
. . .
(case when value50 = 'Yes' then 1 else 0 end)
) as NumYesses
This would be much easier if you normalized the data, so each value was in a separate row. You would do this by having a separate table, called a junction or association table.
Also, you can generate this code in a spreadsheet, such as Excel, by using formulas on the columns names (or by writing a query that uses metadata in your database).
Note: this is generic ANSI SQL, because you don't specify the database. There may be some shortcuts to writing the code in different databases.
Related
I'd like to use a case statement to compare multiple rows on 2 columns. For example, if row 1 column 1 and row 2 column 1 match but row 1 column 2 and row 2 column 2 don't, then xx. I have
CASE
WHEN (pprof.description = pprof.description and PCtrl.[sequence] <> PCtrl.[sequence])
THEN xx
but that doesn't return any values, which I know to be incorrect. I'm new to SQL so apologies if I've got this all wrong.
Edit:
Here's some sample data:
Column 1
Column 2
Column 3
123
-A
-No
123
-B
-Yes
Can't figure out the formatting here but there are 3 columns of data above. I'd like the case statement to evaluate whether column 1 match in 2 different rows (i.e., 123 = 123) and also whether column 2 doesn't (A <> B) and if both those conditions are true, return a value in column 3 (in my case, make the No a Yes, since 123-B is Yes). It might be worth noting that the "Yes" and "No" themselves are built into the larger case statement here:
(CASE WHEN tenure.description not in ('casual','co-op','fswep') THEN CASE WHEN (pprof.description = pprof.description and PCtrl.[sequence] <> PCtrl.[sequence])
THEN CASE WHEN (PEmp.Employee_Number = PEmp3.Supervisor_Number) THEN 'Yes' ELSE 'No' END END END) as 'People Manager'
You will want to do a self join here. Without seeing your data, I can't really give you an answer, but you want something like this.
Update A
Set column_3 = 'YES' /* or put CASE statement here /*
FROM pprof A
INNER JOIN pprof B
ON a.description = b.description
AND a.sequence != b.sequence
You may need more join conditions depending on the form of your data and what you want.
To generate 1mln rows of report with the below mentioned script is taking almost 2 days so, really appreciate if somebody could help me with different script which the report can be generated within 10-15mins please.
The requirement of the report is as following;
Table “cover” contains 5mln rows & 6 columns of data and likewise table “data” contains 500,000 rows and 6 columns.
So, each numbers of the rows in table cover has to go through table date and provide the maximum matches.
For instance, as mentioned on the below tables, there could be 3 matches in row #1, 2 matches in row #2 and 5 matches in row #3 so the script has to select the max selection which is 5 in row #3.
Sample table
UPDATE public.cover_sheet AS fc
SET maxmatch = (SELECT MAX(tmp.mtch)
FROM (
SELECT (SELECT CASE WHEN fc.a=drwo.a THEN 1 ELSE 0 END) +
(SELECT CASE WHEN fc.b=drwo.b THEN 1 ELSE 0 END) +
(SELECT CASE WHEN fc.c=drwo.c THEN 1 ELSE 0 END) +
(SELECT CASE WHEN fc.d=drwo.d THEN 1 ELSE 0 END) +
(SELECT CASE WHEN fc.e=drwo.e THEN 1 ELSE 0 END) +
(SELECT CASE WHEN fc.f=drwo.f THEN 1 ELSE 0 END) AS mtch
FROM public.data AS drwo
) AS tmp)
WHERE fc.code>0;
SELECT *
FROM public.cover_sheet AS fc
WHERE fc.maxmatch>0;
As #a_horse_with_no_name mentioned in the comment to the question, your question is not clear...
Seems, you want to get the number of records which 6 fields from both tables are equal.
I'd suggest to:
reduce the number of select statements, then the speed of query execution will increase,
split your query into few smaller ones (good practice), to check your logic,
use join to get equal data, see: Visual Representation of SQL Joins
use subquery or cte to get result on which you'll be able to update table.
I think you want to get result as follow:
SELECT COUNT(*) mtch
FROM public.cover_sheet AS fc INNER JOIN public.data AS drwo ON
fc.a=drwo.a AND fc.b=drwo.b AND fc.c=drwo.c AND fc.d=drwo.d AND fc.e=drwo.e AND fc.f=drwo.f
If i'm not wrong and above query is correct, the time of execution of above query will reduce to about 1-2 minutes.
Finally, update query may look like:
WITH qry AS
(
-- proper select statement here
)
UPDATE public.cover_sheet AS fc
SET maxmatch = qry.<fieldname>
FROM qry
WHERE fc.code>0 AND fc.<key> = qry.<key>;
Note:
I do not see your data and i know nothing about its structure, relationships, etc. So, you have to change above query to your needs.
I am trying to get a simple count of all the negative and positive values of a specific column on my database. I want to be able to count these values based on another column. What would be the best way to go about handling this problem.
enter image description here
Something like this:
SELECT
SUM(CASE WHEN column > 0 THEN 1 ELSE 0 END) as count_positive,
SUM(CASE WHEN column < 0 THEN 1 ELSE 0 END) as count_negative
FROM
table
You must put the column name, table name, and decide whether 0 is positive, negative or excluded (my choice)
I have to write a case expression in SQL which goes like this,
case condition
if (T_CD = 'Y')
Case C_CD = 'H3'
set R_ID = 3 and RS_ID = 25
CASE A_FLG = 'N' and Mod = 'D'
set R_ID = 3 and RS_ID = 31
Both R_ID and RS_ID populate columns in a different table and have to be derived as per condition above.
My question is - Since I want 2 separate fields out of my case expression, will a single Case give out 2 resultant field values for me. Or Do I have to write 2 different case expressions for it.
If your dbms supports row types, maybe this works for you:
select case when a = 1 then (1,2) else (3,4) end from testtable;
The SQL Validator says:
The following feature outside Core SQL-2003 is used:
T051, "Row types"
I've got a table called datapoints with about 150 columns and 2600 rows. I know, 150 columns is too much, but I got this db after importing a csv and it is not possible to shrink the number of columns.
I have to get some statistical stuff out of the data. E.g. one question would be:
Give me the total number of fields (of all columns), which are null. Does somebody have any idea how I can do this efficiently?
For one column it isn't a problem:
SELECT count(*) FROM datapoints tb1 where 'tb1'.'column1' is null;
But how can I solve this for all columns together, without doing it by hand for every column?
Best,
Michael
Building on Lamak's idea, how about this idea:
SELECT (N * COUNT(*)) - (
COUNT(COLUMN_1)
+ COUNT(COLUMN_2)
+ ...
+ COUNT(COLUMN_N)
)
FROM DATAPOINTS;
where N is the number of columns. The trick will be in making the summation series of COUNT(column), but that shouldn't be too terrible with a good text editor and/or spreadsheet.
i don't think there is an easy way to do it. i'd get started on the 150 queries. you only have to replace one word (column name) each time.
Well, COUNT (and most aggregations funcions) ignore NULL values. In your case, since you are using COUNT(*), it counts every row in the table, but you can do that on any column. Something like this:
SELECT TotalRows-Column1NotNullCount, etc
FROM (
SELECT COUNT(1) TotalRows,
COUNT(column1) Column1NotNullCount,
COUNT(column2) Column2NotNullCount,
COUNT(column3) Column3NotNullCount ....
FROM datapoints) A
To get started it's often helpful to use a visual query tool to generate a field list and then use cut/paste/search/replace or manipulation in a spreadsheet program to transform it into what is needed. To do it all in one step you can use something like:
SELECT SUM(CASE COLUMN1 WHEN NULL THEN 1 ELSE 0 END) +
SUM(CASE COLUMN2 WHEN NULL THEN 1 ELSE 0 END) +
SUM(CASE COLUMN3 WHEN NULL THEN 1 ELSE 0 END) +
...
FROM DATAPOINTS;
With a visual query builder you can quickly generate:
SELECT COLUMN1, COLUMN2, COLUMN3 ... FROM DATAPOINTS;
You can then replace the comma with all the text that needs to appear between two field names followed by fixing up the first and last fields. So in the example search for "," and replace with " WHEN NULL 1 ELSE 0 END) + SUM(CASE " and then fix up the first and last fields.