MySQL: Multiple rows to multiple fields? - mysql

I have this table:
userid | property
1 | propA
1 | propC
2 | propA
2 | propB
And need this output for an csv export/import
userid;propA;propB;probC
1;yes;no;yes
2;yes;yes;no
Is that possible without any script language like php?
It would be totally okay for me if "yes" and "no" are just "1" and "0" (e.g.) but it is important that I need just one row for each user and one field for each property.

You can use conditional aggregation. However, your format is not CSV (hint: the "C" means comma).
To get that format, you can do:
select t.userid,
max(case when t.property = 'propA' then 'Yes' else 'No' end) as PropA,
max(case when t.property = 'propB' then 'Yes' else 'No' end) as PropB,
max(case when t.property = 'propC' then 'Yes' else 'No' end) as PropC
from table t
group by t.userid;
This happens to work because "Yes" is later in the alphabet than "No". Personally, I would just use numbers, 0 and 1:
select t.userid,
max(t.property = 'propA') as PropA,
max(t.property = 'propB') as PropB,
max(t.property = 'propC') as PropC
from table t
group by t.userid;

Related

How to select the row value based on preference order in the table using MySql

I have table as data_attributes with a column data_type
SELECT * FROM DATA_ATTRIBUTES;
DATA_TYPE
----------
NAME
MOBILE
ETHINICITY
CC_INFO
BANK_INFO
ADDRESS
Bank_info, CC_info classified as Risk1,
Mobile, Ethinicity classified as Risk2,
Name, Address classified as Risk3
I should get the Risk classification as output,
For eg: If any of the row contains Risk1 type then output should be Risk1,
else if any of the row contains Risk2 type then output should be Risk2,
else if any of the row contains Risk3 type then output should be Risk3
I wrote below query for this
SELECT COALESCE(COL1,COL2,COL3) FROM
(SELECT
CASE WHEN DATATYPE IN ('BANK_INFO','CC_INFO') THEN 'RISK1' ELSE NULL END AS COL1,
CASE WHEN DATATYPE IN ('MOBILE','ETHINICITY') THEN 'RISK2' ELSE NULL END AS COL2,
CASE WHEN DATATYPE IN ('NAME','ADDRESS') THEN 'RISK3' ELSE NULL END AS COL3
FROM DEMO.TPA_CLASS1) A;
The required output is: Risk1 ( Only 1 value )
Please give some idea to achieve this.
You can use conditional aggregation:
SELECT
CASE
WHEN MAX(DATATYPE IN ('BANK_INFO','CC_INFO')) = 1 THEN 'RISK1'
WHEN MAX(DATATYPE IN ('MOBILE','ETHINICITY')) = 1 THEN 'RISK2'
WHEN MAX(DATATYPE IN ('NAME','ADDRESS')) = 1 THEN 'RISK3'
END AS RISK
FROM DEMO.TPA_CLASS

Summing Custom Column

First Stackoverflow question - so go easy on me :).
Hello, I am trying to flag items as "Attributed" using the following query that I have written. Essentially, if a patient ID has a PERSON_PROVIDER_RELATIONSHIP flag, they are given a 1 for that instance. If they have another type of flag (there are two other possible flags you can receive). Everything goes fine (the assigning of "1" to the instances of PERSON_PROVIDER_RELATIONSHIP), but then when I try to sum that custom column I created ("Attribution"), I get this error: (Column "Attribution" does not exist). I get this error whether I try to make another column that does the summing or when I add a "having" clause to the end where I state I only want to see records with a sum of >0. Any help would be appreciated here! I'm using MySQL to write this and am happy to provide any clarifying information.
select distinct c.empi_id as "Patient",
c.incurred_from_date as "Service Date",
(case when c.billing_organization_source_id IN ('xxxx','yyyy') then 1 else 0
end) as "In-Network Indicator",
(case when t.ref_record_type = 'PERSON_PROVIDER_RELATIONSHIP' then 1 else 0
end) as "Attribution",
(sum("Attribution") over (partition by c.empi_id)) as "Attribution Flag",
p.cleanprovidername as "Provider", t.ref_record_type
from ph_f_annotated_claim c
left outer join PH_F_Attribution_Component_Data_Point t
on t.empi_id = c.empi_id and t.population_id = c.population_id
inner join ph_d_personnel_alias a
on a.prsnl_id = t.prsnl_id
inner join xxxx_xxxx_xxxx_xxxx p
on a.prsnl_alias_id = p.NPI
where (c.bill_type_code like '33%'
or c.bill_type_code like '32%'
or c.bill_type_code like '033%'
or c.bill_type_code like '032%')
and c.source_description = 'MSSP Claims'
and c.incurred_from_date >= '2015-12-01'
and c.incurred_from_date <= '2017-01-31'
and c.population_id = '2feb2cb1-be55-4827-a21f-4e2ef1a40340'
and p.DegreeName IN ('MD','DO')
and a.prsnl_alias_type = 'NPI'
and p.PrimaryPHO = 'Yes'
group by c.empi_id, c.incurred_from_date, c.billing_organization_source_id,
p.cleanprovidername, t.ref_record_type
You can't use an aliased column name as an expression in the same SELECT clause. You have to do something like this:
sum(case when t.ref_record_type = 'PERSON_PROVIDER_RELATIONSHIP' then 1 else 0 end) over (partition by c.empi_id) as "Attribution Flag"

Select a 'virtual' column if another column has a value or is null in a SQL view

I want to select ALWAYS a column in my view, and set it with CASES.
example:
SELECT isDone
,doneN
from...
I have to set isDone in this way:
if done is 1 isDone is 'yes'
if done is 0 isDone is 'no'
(doneN is a column from another table, isDone instead doesn't exist in other tables, so it's a "virtual" column)
Thank you in advice
Is this what you want?
select (case when doneN = 1 then 'yes' else 'no' end) as isDoneN
. . .
You didn't specify whether 'done' will always be 0 or 1. If there are more values or you want to catch other values, use something like this:
select (case when done = 1 then 'yes'
when done = 0 then 'no'
else '' end) as isDone
, doneN
from ...
If the 'done' is constrained to be 0 or 1, you can use:
select (case when done = 1 then 'yes'
else 'np' end) as isDone
, doneN
from ...

How to select a row by a certain amount of similar data

I'm about to build some sort of function or query where I can check if a certain record already exists in the database. The following rules apply:
The table has 6 columns
My yet-to-build-query has access to a complete row-object (all 6 values)
This query should find each row with at least 4 out of 6 corresponding values from the object I passed
Using MySQL
Is it even possible to build a query like this? My goal is to have a function which can return true if it's likely that a row like the passed object is already existing in the database.
Is my only option to make a query with multiple where-statements (where I try for each combination 4 different values)?
pseudo:
function getSimilarRow(Row_Object $row)
{
//select *
//from table_x
//where 4 out of 6 properties from object $row apply
}
You could use a case statement in the where clause for each property you are trying to match. If it meets the criteria then give the case statement a value of 1; if it doesn't then give it 0. The sum of the cases should then be >= 4.
I'm not that familiar with MySQL but the following will work (I knocked up a quick SQL Fiddle to show it working):
select * from SomeTable where
(case when propertyOne = 'value1' then 1 else 0 end) +
(case when propertyTwo = 'value2' then 1 else 0 end) +
(case when propertyThree = 'value3' then 1 else 0 end) +
(case when propertyFour = 'value4' then 1 else 0 end) +
(case when propertyFive = 'value5' then 1 else 0 end) +
(case when propertySix = 'value6' then 1 else 0 end) >= 4
Obviously you could change your logic in each clause if you'd prefer them to be likes or anything. You could even apply a weighting to each column by using something other than just 1 if you needed to get really creative.

SQL How to replace values of select return?

In my database (MySQL) table, has a column with 1 and 0 for represent true and false respectively.
But in SELECT, I need it replace for true or false for printing in a GridView.
How to I make my SELECT query to do this?
In my current table:
id | name | hide
1 | Paul | 1
2 | John | 0
3 | Jessica | 1
I need it show thereby:
id | name | hide
1 | Paul | true
2 | John | false
3 | Jessica | true
You have a number of choices:
Join with a domain table with TRUE, FALSE Boolean value.
Use (as pointed in this answer)
SELECT CASE WHEN hide = 0 THEN FALSE ELSE TRUE END FROM
Or if Boolean is not supported:
SELECT CASE WHEN hide = 0 THEN 'false' ELSE 'true' END FROM
I got the solution
SELECT
CASE status
WHEN 'VS' THEN 'validated by subsidiary'
WHEN 'NA' THEN 'not acceptable'
WHEN 'D' THEN 'delisted'
ELSE 'validated'
END AS STATUS
FROM SUPP_STATUS
This is using the CASE
This is another to manipulate the selected value for more that two options.
You can do something like this:
SELECT id,name, REPLACE(REPLACE(hide,0,"false"),1,"true") AS hide FROM your-table
Hope this can help you.
If you want the column as string values, then:
SELECT id, name, CASE WHEN hide = 0 THEN 'false' ELSE 'true' END AS hide
FROM anonymous_table
If the DBMS supports BOOLEAN, you can use instead:
SELECT id, name, CASE WHEN hide = 0 THEN false ELSE true END AS hide
FROM anonymous_table
That's the same except that the quotes around the names false and true were removed.
You can use casting in the select clause like:
SELECT id, name, CAST(hide AS BOOLEAN) FROM table_name;
I saying that the case statement is wrong but this can be a good solution instead.
If you choose to use the CASE statement, you have to make sure that at least one of the CASE condition is matched. Otherwise, you need to define an error handler to catch the error. Recall that you don’t have to do this with the IF statement.
SELECT if(hide = 0,FALSE,TRUE) col FROM tbl; #for BOOLEAN Value return
or
SELECT if(hide = 0,'FALSE','TRUE') col FROM tbl; #for string Value return
in Postgres 11 I had to do this:
type is an int
SELECT type,
CASE
WHEN type = 1 THEN 'todo'
ELSE 'event'
END as type_s
from calendar_items;
replace the value in select statement itself
(CASE WHEN Mobile LIKE '966%' THEN (select REPLACE(CAST(Mobile AS nvarchar(MAX)),'966','0')) ELSE Mobile END)