How to group by column and ignore NULLS within rows - tsql

Hi have a table like this:
langaugeCode titleText introText
en WeeklyTitle NULL
en NULL This text
de HereItIs NULL
de NULL ThereThere
Essentailly I want to group by language code but ignore the columns within a row that are NULL.
I would like to transform this table to:
langaugeCode titleText introText
en WeeklyTitle This text
de HereItIs ThereThere

You may try aggregating by languageCode and taking the maximum value of each column:
SELECT
languageCode,
MAX(titleText) AS titleText,
MAX(introText) AS introText
FROM yourTable
GROUP BY
languageCode;
Demo
This works because the MAX() aggregate function by default ignores NULL values. So, assuming you only have a single non NULL value for each language code, it would be retained during the aggregation.

You can add where condition for not null check for the columns you don't want null value.

I'd "merge" it by doing this:
Make a two tables (t1 and t2) and make a natural join on it.
SELECT
t2.languageCode, t1.titleText, t2.introText
FROM (SELECT
yt1.languageCode, yt1.titleText, yt1.introText
FROM yourTable yt1
GROUP BY
languageCode) t1, yourTable t2
WHERE
t1.languageCode = t2.languageCode
GROUP BY
t2.languageCode, t1.titleText, t2.introText;
Try it ;)

Related

How can I restrict a result to only include rows where one specific field is unique with UNION Select statement in BigQuery?

I have the following code. I try to stitch the two tables together, but restrict it to only add duplicate Opportunity_ID once, and then from the second table (OpportunitiesUpdates).
SELECT
Opportunity.Account_Name,
Opportunity.Opportunity_Name,
Opportunity.Opportunity_Owner,
Opportunity.Opportunity_ID
FROM
Opportunity
UNION DISTINCT
SELECT
OpportunityUpdates.Account_Name,
OpportunityUpdates.Opportunity_Name,
OpportunityUpdates.Opportunity_Owner,
OpportunityUpdates.Opportunity_ID
FROM
OpportunityUpdates
WHERE OpportunityUpdates.Opportunity_ID <> Opportunity.Opportunity_ID
This code consolidates all records from both tables (by Opportunity_ID) and gives priority to the OpportunityUpdates table based on Opportunity_ID.
It assumes that the same Opportunity_ID could be in either table ("duplicates"), but that within each table an Opportunity_ID is unique. It also assumes that Opportunity_ID is not nullable (never null).
SELECT DISTINCT
IF(ou.Opportunity_ID IS NOT NULL, ou.Account_Name, o.Account_Name) Account_Name,
IF(ou.Opportunity_ID IS NOT NULL, ou.Opportunity_Name, o.Opportunity_Name) Opportunity_Name,
IF(ou.Opportunity_ID IS NOT NULL, ou.Opportunity_Owner, o.Opportunity_Owner) Opportunity_Owner,
COALESCE(ou.Opportunity_ID, o.Opportunity_ID) Opportunity_ID
FROM OpportunityUpdates ou
FULL OUTER JOIN
Opportunity o
ON o.Opportunity_ID = ou.Opportunity_ID

PostgreSQL query with unnest returns no result row for null values

I am trying to query the values that divides comma separated values in a column as different records ,I could not get the values if the column has null values, Below is the example
Table name: test
id,name,list
1,a, a1,b1
2,b, null
3,c,c1
Query which is used
select id,name,unnest(string_to_array(list,',')) from test;
Result:
1,a,a1
1,a,b1
3,c,c1
But I need to consider the null values and return the result as below ,I tried using coalesce but that did not work, kindly help me out with the solution
Expected result:
1,a,a1
1,a,b1
2,b,null
3,c,c1
Use unnest() with an outer join:
select t.id, t.name, u.element
from test t
left join unnest(string_to_array(t.list,',')) on true
order by t.id;

Fetch rows from postgres table which contains a specific id in jsonb[] column

I have a details table with adeet column defined as jsonb[]
a sample value stored in adeet column is as below image
Sample data stored in DB :
I want to return the rows which satisfies id=26088 i.e row 1 and 3
I have tried array operations and json operations but it does'nt work as required. Any pointers
Obviously the type of the column adeet is not of type JSON/JSONB, but maybe VARCHAR and we should fix the format so as to convert into a JSONB type. I used replace() and r/ltrim() funcitons for this conversion, and preferred to derive an array in order to use jsonb_array_elements() function :
WITH t(jobid,adeet) AS
(
SELECT jobid, replace(replace(replace(adeet,'\',''),'"{','{'),'}"','}')
FROM tab
), t2 AS
(
SELECT jobid, ('['||rtrim(ltrim(adeet,'{'), '}')||']')::jsonb as adeet
FROM t
)
SELECT t.*
FROM t2 t
CROSS JOIN jsonb_array_elements(adeet) j
WHERE (j.value ->> 'id')::int = 26088
Demo
You want to combine JSONB's <# operator with the generic-array ANY construct.
select * from foobar where '{"id":26088}' <# ANY (adeet);

How to check if json inner field is EMPTY?

One of the column ( called details ) in my table is of jsonb data type and have data format somthing like this:
{"media_height":"350", "media_height":"450", "media_alt":"", "file_name":"myfile.jpeg"}
This field I am taking in case when because I want to mark the records of missing alt text.
SELECT
distinct ON ( p.property_name )
p.id, p.property_name,
CASE
WHEN mma.id IS NULL THEN 'Z'
WHEN mma.details->'media_alt'::TEXT IS NULL THEN 'NO'
ELSE 'YES' END as has_media_alt
FROM properties p
LEFT JOIN marketing_media_associations mma ON ( mma.reference_id = p.id )
GROUP BY p.id, p.property_name , mma.details->'media_alt', mma.id
ORDER BY p.property_name, has_media_alt ASC
The above query gives me accurate results for Z, but it never goes in NO block. What I am missing here?
An empty string is not the same as NULL, you probably want:
WHEN nullif(mma.details->>'media_alt', '') IS NULL THEN 'NO'
You don't need to cast to text, if you use ->> which returns the value as text directly.

Another way of returning rows if any of the columns has different value for the same id

Is there any other way for returning rows for the same id by joining two tables and return the row if any of the columns value for the same id is different.
Select Table1.No,Table2.No,Table1.Name,Table2.Name,Table1.ID,Table2.ID,Table1.ID_N,Table2.ID_N
From MyFirstTable Table1
JOIN MySecondTable Table2
ON Table1.No=Table2.No where Table1.ID!=Table2.ID or Table1.ID_N != Table2.ID_N
In the example above , I have only two columns I need to check but in my real case there are at least 20 .
Is there any other statment I can use instead of enumerating each column in the where codition?
...WHERE BINARY_CHECKSUM(Table1.*) <> BINARY_CHECKSUM(Table2.*)
or
...WHERE BINARY_CHECKSUM(Table1.Field1, Table1.Field2, ...) <> BINARY_CHECKSUM(Table2..Field1, Table2.Field2, ...)
*this assumes you have no blob fields in your tables
http://technet.microsoft.com/en-us/library/ms173784.aspx
If No is a PK
Select Table1.No,Table1.Name,Table1.ID,Table1.ID_N
From MyFirstTable Table1
except
Select Table1.No,Table1.Name,Table1.ID,Table1.ID_N
From MySecondTable Table1