Null values not being returned in Postgresql - sql

I have two tables in Postgresql, which I need to perform the union taking the null values, to add other values in another column of the junction.
Table one:
I filtered by date, because this data is generated daily and I only need the current_date
Table two: All names.
In table two I have 9 names that are not found in table one.
When I try to perform the join, I only get the 9 names from table one as a result.
Trying with date from table one to current_date
But if I don't filter the date from table one, the null value is returned.
That is, the name that is in table two but not in table one.
What I need is to join the two tables and where there is no asset referring to the second table, fill it with 0 (zero).
In this part I understood that I must use COALESCE(vcm.ativo,0).
But first I need the names of the second table to appear as well.
The result should be like this:
If someone could help me, I'll be grateful.

As pointed out in a comment by the asker, the solution turned out to be
with todays_data as (
select vcm.cooperativa, vcm.ativo
from sga_bi.veiculos_coop_mensal as vcm
where data = current_date
)
select coop.nome, COALESCE(vcmm.ativo,0)
from sga.cooperativas as coop
left outer join todays_data as vcmm
on coop.nome = vcmm.cooperativa

Related

How to get the differences between two - kind of - duplicated tables (sql)

Prolog:
I have two tables in two different databases, one is an updated version of the other. For example we could imagine that one year ago I duplicated table 1 in the new db (say, table 2), and from then I started working on table 2 never updating table 1.
I would like to compare the two tables, to get the differences that have grown in this period of time (the tables has preserved the structure, so that comparison has meaning)
My way of proceeding was to create a third table, in which I would like to copy both table 1 and table 2, and then count the number of repetitions of every entry.
In my opinion, this, added to a new attribute that specifies for every entry the table where he cames from would do the job.
Problem:
Copying the two tables into the third table I get the (obvious) error to have two duplicate key values in a unique or primary key costraint.
How could I bypass the error or how could do the same job better? Any idea is appreciated
Something like this should do what you want if A and B have the same structure, otherwise just select and rename the columns you want to confront....
SELECT
*
FROM
B
WHERE NOT EXISTS (SELECT * FROM A)
if NOT EXISTS doesn't work in your DBMS you could also use a left outer join comparing the rows columns values.
SELECT
A.*
from
A left outer join B
on A.col = B.col and ....

How can I delete duplicate rows in the same table that have identical CLOB data?

I have a table in Oracle of which one of the columns (named CONTENTSTRING) is a CLOB. However, some of the rows in this table have identical data in this column. What I'd like to do is remove all the rows except for one that have this identical data. How can I accomplish this?
Googling around, I see a ton of examples for comparing two columns. I also see examples comparing between two different tables. What I don't see is an example using one table and just comparing the rows! I do think I might need to use this function: dbms_lob.compare. However, I'm still not sure how I can set this function up.
From a programmer's perspective, I would think maybe I should do something like:
SELECT CONTENTSTRING FROM TABLE_ALPHA A
and then somehow do another select from the same table as TABLE_ALPHA B, and then use dmbs_lob.compare to compare the two columns. If the row numbers are different AND the column contents are equal, then the row from TABLE_ALPHA B can be deleted.
I think that's the right approach, but how exactly would I write this out in Oracle using SQL? I would appreciate any help or resources on this. Thanks!
DELETE
FROM TABLE_ALPHA A
WHERE EXISTS (
SELECT 1 FROM TABLE_ALPHA B
WHERE DBMS_LOB.COMPARE(A.CONTENTSTRING, B.CONTENTSTRING) = 0
AND A.ROWID > B.ROWID
)
This deletes all dublicates except first one.
This answer assumes that you have a primary key field in the source table (I called it id).
You can use a subquery to list the ids of the duplicated records : this works by self-joining the table with dbms_lob.compare and a comparison clause on the id. If duplicate rows exist with the same CLOB content, all ids but the most ancient (ie the smallest) are selected. The outer query just deletes the selected ids. The NVL will consider NULL contents as duplicates (if that's not relevant for your use case, just remove them).
DELETE FROM TABLE_ALPHA
WHERE id IN (
SELECT b.id
FROM TABLE_ALPHA a
INNER JOIN TABLE_ALPHA b
ON
(
(a.contentString IS NULL AND b.contentString IS NULL)
OR dbms_lob.compare(a.CONTENTSTRING, b.CONTENTSTRING) = 0
)
AND b.id > a.id
);
See this db fiddle.

SQL/SpatiaLite: Combining two tables containing some identical rows and keeping some nonidentical ones

I need to combine two tables. Both of them have three column names that match and some other ones. The data doesn't match. I'm not trying to do a join on the values - the best I could describe this would be selective appending. I tried union but that doesn't work due to the different columns.. can this be even done like this? Or would I first have to create a new table and then insert from the other two?
Image for clarification:
Try to use union this way:
select somevalue1,somevalue2,somevalue3,value1_t1,value2_t1,cast(null as int) as value2_t2,cast(null as int) as value3_t2
from table1
union all
select somevalue1,somevalue2,somevalue3,null,null,value2_t2,value3_t2
from table2
In 1st query you need convert not maching column to target format.
In 2ng you can use null insetad of not maching column.

How to find rows which differ by a given amount in SQL?

So I have a data table which looks like
Where each row has a timestamp column in Unix time. I need to find all the places where two entries with the same resource_id are x(day month, year etc) amount of time apart, so I need a query that will go through and look at the differences between one row and the next and spit back the ones which differ by more than a specified amount.
Anybody have any ideas on how to do this? Thanks in advance
You may use a cross join to compare every row in the table with every other row in the table then compare the field. For example the following will return where the two rows are 2 months apart.
SELECT t.resource_id, s.resource_id
FROM table t CROSS JOIN table s
WHERE TIMESTAMPDIFF(MONTH,t.timestamp,s.timestamp) = 2
Note that this could be extremely slow if the table is large. Or according to the MySQL docs just saying JOIN without specifying the condition will result in a cartesian product which is equivalent to a cross join.

Returning an Access recordset with zeros instead of nulls

Here's the problem:
I have an Access query that feeds a report, which sometimes doesn't return any records for certain criteria. I would like to display zeros in the report instead of an empty line (an empty recordset is currently being returned).
Is there an SQL solution that (perhaps using some kind of union statement and/or nested SQL) always returns one record (with zeros) if there are not matching records from the initial query?
One possible solution would be to create a second table with the same primary key, and add just one record. In your query, choose as join type all records in the second table, including those with no matching records in the first one. Select as output all fields in the first table.
You can materialize a one-row table with zero for all columns. This is a slight pain to achieve in Access (ACE, Jet, whatever) because it doesn't support row constructors and the FROM must resolve to a base table. In other words, you'll need a table that is guaranteed to always contain at least one row.
This isn't a problem for me because my databases always include auxilliary tables e.g. a calendar table, a sequence table of integers, etc. For exmaple, to materialize a table one-row, all-zeros table using my 3000 row Calendar table:
SELECT DISTINCT 0 AS c
FROM Calendar;
I can then UNION my query with my materialized table but include an antijoin to ensure the all-zeros row only appears in the resultset when my query is the empty set:
SELECT c
FROM T
UNION
SELECT 0
FROM Calendar
WHERE NOT EXISTS (
SELECT c
FROM T
);
Note the use of UNION allows me to remove the DISTINCT keyword and the AS clause ("column alias") from the materialized table.