count duplicates in sql for 1 column - sql

how i can fill out "category" in table 1 in the case where there are multiple in table 2? I would like to fill as multiple if there are multiple categories per object.
attempt:
select t1.*,
case case when count(t2.category)>1 then 'Multiple' else cast(t2,category as varchar)
from table1 t1
left join table 2 t2 on t2.object=t1.object
Issue, its asking for group by, i have over 80 columns, is there anyway to bypass group by?

Create an expression for the value using a subquery:
select
t1.*,
case (select count(*) from table2 t2 where t2.object = t1.object)
when 0 then 'None'
when 1 then (select cast(max(t2,category) as varchar)) from table2 t2 where t2.object = t1.object)
else 'Multiple'
end as category
from table1 t1
This avoids listing all columns in either the group by clause in the case of aggregation approach, or the select clause in the case of using a query over a subquery.
I added None as a result because you used a left join, indicating that joining rows are optional.
This wouldn't perform well with large numbers of rows, but should be fine with modest table sizes.

Can you try this:
select
distinct
t1.*,
case when c.object is not null then 'Multiple' else b.category end as category
from
table1 t1
left outer join
table2 t2
on t1.object = t2.object
left outer join
(select object from table2 group by object having count(*) > 1) c
on t1.object = c.object

Related

SQL statement to check if data exists in one table and not in two other tables

I'm creating 1 temp table (temp1) using table1.
and I want to check if data from temp table is present in table1 and table2.
table1 and table2 have same columns.
It's difficult to assess exactly what you need without further detail, but you could try a LEFT JOIN and a COUNT here to indicate whether there are any matching rows (whereby anything over 0 indicates matching rows)
SELECT
COUNT(*) AS matching_rows
FROM
(
SELECT
1 AS 'ColumnA'
) AS T1
LEFT OUTER JOIN
(
SELECT
2 AS 'ColumnA'
) AS T2
ON T1.ColumnA = T2.ColumnA
WHERE
T2.ColumnA IS NOT NULL
You can also use an INNER JOIN for this:
SELECT
COUNT(*) AS matching_rows
FROM
(
SELECT
1 AS 'ColumnA'
) AS T1
INNER JOIN
(
SELECT
2 AS 'ColumnA'
) AS T2
ON T1.ColumnA = T2.ColumnA

Select Multiple value from a table but group by one value

I am trying to select multiple values from two tables but i want to group by single value. I have tried using max(value) in select but max is returning the greatest one and not the exact one.
Here are my tables
The result i need is something like this
Result : HeadQuarterId - A, PropertyName - Name1, Amount - 102
HeadQuarterId - B, PropertyName - Name5, Amount - 30
Here is my query
SELECT Headquarterid,Max(PropertyName),sum(Amount)
FROM Table1 A LEFT OUTER JOIN Table2 B
ON A.Propetyid = B.PropertyId
GROUP BY Headquarterid
Here i have used Left Outer Join so that i will get all the data from left table even it is not available in right table.
Also i cannot use A.HeadquarterID = A.PropertyId in where condition since i have other dependency in that table. Please suggest someother way to achieve this result.
I think I understand. You want the headquarters with the maximum value, which happens to be A. If so:
select t1.*, sum(t2.amount) over () as total
from t1 left join
t2
on t2.PropertyId = t1.PropertyId
order by t2.amount desc
fetch first 1 row only;
Note: Not all databases support fetch first. It might be spelled limit or use select top (1) for instance.
I would recommend to get the headquartename per ID in a cte / subquery, then join it again to T1 and left join T1 to T2 in a second cte / subquery. This way you can calculate your sums basing on a single group:
WITH cte AS(
SELECT ROW_NUMBER() OVER (PARTITION BY t1.ID ORDER BY CASE WHEN t1.ID = t1.PROPERTYID THEN 0 ELSE 1 END) rn, t1.ID, t1.Name
FROM t1
),
cte2 AS(
SELECT c.name cName, t1.*, t2.Value
FROM t1
INNER JOIN cte c ON c.ID = t1.ID AND c.rn = 1
LEFT JOIN t2 ON t1.Propertyid = t2.propertyid
)
SELECT c2.id, c2.cname, sum(c2.value) value
FROM cte2 c2
GROUP BY c2.id, c2.cname
See SQLFiddle for details: http://sqlfiddle.com/#!18/8bf66/13/2
Of course you can build the first cte without the row_number only by using the WHERE ID = PROPERTYID - matter of taste I'd say...
As per your sample data you want window function :
select distinct t1.HeadQuarterId,
max(t1.PropertyName) over (partition by t1.HeadQuarterId) as PropertyName,
sum(t2.amount) over (partition by t1.HeadQuarterId) as amount
from t1 left join
t2
on t2.PropertyId = t1.PropertyId;
This provided the result i expected.
SELECT HQTRS1 AS headId,Max(LLORD1) AS headName, sum(Amount) AS amount
FROM
(SELECT DISTINCT HeadQuarterId AS HQTRS1, PropertyName AS LLORD1 FROM Table_1 WHERE HeadQuarterId = PropertyId) AS temp
INNER JOIN Table_1 AS A ON A.HeadQuarterId = temp.HQTRS1
LEFT OUTER JOIN Table_2 B
ON B.PropertyId = A.PropertyId
GROUP BY HQTRS1

How can I make a join between two tables keeping specific records from each table according to a condition

I have two tables t1, t2 I want for example to get all the results from t1 except when itemType = '01' in which case I want to keep the correspondent itemType='01' record from t2, and this is the only record I want from t2.
Try a case statement for the field
This way ONLY that field is selected based on the condition you described
Assuming in the example below an inner join, however we could changes this to an outer join and add a little logic for handling nulls.
Depending on the relationship in the data, you may need to group by to get to the correct level of information/avoid duplicates. Still the example should help
For example,
select t1.field1, t1.field2, etc,
case
when t1.itemType = '01' then t2.itemType
else t1.itemType
end
from
(
(select * from tableA) as T1
inner join
(select * from tableB) as T2
On T1.key1 = T2.key1
)
I suspect that you want UNION ALL and not a JOIN:
select * from t1
where itemtype <> '01'
union all
select * from t2
where itemtype = '01'
I think a left join with filtering parses into the description you have given:
select t1.*, t2.*
from t1 join
t2
on t2.? = t1.? and -- however you define corresponding
t2.itemType = '01'
where t1.itemType <> '01';

Optimizing a SELECT with sub SELECT query in Oracle

Select id,
(Select sum(totalpay)
from Table2 t
where t.id = a.id
and t.transamt > 0
and t.paydt BETWEEN TRUNC(sysdate-0-7) and TRUNC(sysdate-0-1)) As Pay
from Table1 a
In spite of having indexes on transamt, paydt and id, the cost of the sub-query on Table2 is very expensive and requires a FULL TABLE scan.
Can this sub-query be optimized in any other way?
Please help.
Select t.id,
sum(totalpay) as Pay
from Table2 t join Table1
Where t.id = Table1.id
and t.transamt > 0
and t.paydt BETWEEN TRUNC(sysdate-0-7) and TRUNC(sysdate-0-1)
group by t.id
Try this:
Select a.id,
pay.totalpay
from Table1 a
(Select t.id, sum(totalpay) totalpay
from Table2 t
where t.transamt > 0
and t.paydt BETWEEN TRUNC(sysdate-0-7) and TRUNC(sysdate-0-1)
group by t.id
) As Pay
where a.id = pay.id
push group by joining columns (id column in this example) into subquery to calculate results for all values in Table2 and then join with Table1 table.
In original query you calculate result for every crow from Table1 table reading full Table2 table.

Table join comparing and creating a new column using that compare

I have 2 tables... table1 and table2.
I want to display all serial numbers from table1
table2 has also has serial numbers in it
I would like to compare the serial numbers in table1 with table2
I would then like to display all the serial numbers in table1 and have a second column with a yes if the serial number was in table1 or a no if it wasn't
Is this possible to do with a sql statement or do I have to build a seperate table? i'm running sql-server.
If serial numbers in each table are unique then you could use:
SELECT Table1.SerialNumber,
CASE WHEN Table2.SerialNumber IS NULL THEN 'No' ELSE 'Yes' END AS [IsInTable2]
FROM Table1.SerialNumber
LEFT JOIN Table2
ON Table2.SerialNumber = Table1.SerialNumber
If there are Duplicates in one or both tables then either of the following will work:
SELECT DISTINCT
Table1.SerialNumber,
COALESCE([IsInTable2], 'No') [IsInTable2]
FROM Table1.SerialNumber
OUTER APPLY
( SELECT TOP 1 'Yes' [IsInTable2]
FROM Table2
WHERE Table2.SerialNumber = Table1.SerialNumber
) Table2
SELECT DISTINCT
Table1.SerialNumber,
CASE WHEN Table2.SerialNumber IS NULL THEN 'No' ELSE 'Yes' END [IsInTable2]
FROM Table1.SerialNumber
LEFT JOIN
( SELECT DISTINCT SerialNumber
FROM Table2
) Table2
ON Table2.SerialNumber = Table1.SerialNumber
If we assume that the serial numbers are unique in each table then you can do an outer join. Using a LEFT OUTER JOIN will grab you all rows from the left side and optionally grab you any matching rows on the right side. Then you can do a comparison to see if a matching row was found in table2.
SELECT t1.serial, CASE WHEN t2.serial IS NULL THEN 'No' ELSE 'Yes' END
FROM table1 t1
LEFT OUTER JOIN table2 t2 ON t1.serial = t2.serial;
Try this
SELECT t1.serialnumber as serialnumber, Case
WHEN t1.serialnumber = t2.serialnumber then 'YES' else 'NO' END
FROM table1 t1
LEFT JOIN table2 t2 with (nolock) on t1.serialnumber = t2.serialnumber;
Hopefully that should work