How to filter inconsistent records in sqlite - sql

Say I have SQLite table with the following records:
recID
productID
productName
1
1
Product A
2
2
Product B
3
2
Product C
4
3
Product D
5
3
Product D
recID = primary key, auto increment.
If I run:
SELECT productID, productName
FROM table
GROUP BY productID, productName
Result is:
productID
productName
1
Product A
2
Product B
2
Product C
3
Product D
As you can see, productID 2 has inconsistent productName: Product B and Product C. How do I run query just to detect the inconsistent ones? Eg I want the result to be:
productID
productName
2
Product B
2
Product C

Use EXISTS to get a productID with more than 1 productNames:
SELECT t1.productID, t1.productName
FROM tablename t1
WHERE EXISTS (
SELECT *
FROM tablename t2
WHERE t2.productID = t1.productID AND t2.productName <> t1.productName
);
Or, for a small dataset use aggregation in a subquery which counts the distinct number of productNames of each productID, with the operator IN:
SELECT productID, productName
FROM tablename
WHERE productID IN (
SELECT productID
FROM tablename
GROUP BY productID
HAVING COUNT(DISTINCT productName) > 1
);

Related

SQL retrieve rows based on column condition

Say I have below tables
Order Table
OrderNo CategoryID CountryID ServiceTypeID
100 1 3 1
200 2 5 2
300 3 4 4
400 1 2 9
1 service Type might belong to many category type
Category Table
ID Name ServiceTypeID
1 x 1
2 x 2
3 x 1
ServiceType table
ID Name
1 xx
2 xx
3 xx
Tracking Table
OrderNo CountryID TrackingTypeID
100 2 3
200 1 4
100 3 2
400 5 1
200 2 6
Reviewd Table
OrderNo
300
100
200
I want to write a query with below requirements
Order must belong to serviceTypeID = 1 or 2
And If the orderNo has a categoryID = 1
I want that record to be retrieved only if
there's a record in tracking table for that
orderNo with same countryID as in Order table
and if that orderNo doesn't have tracking type of id (0,7,1) in tracking table
Else for all other orders with any other category excluding orders which are not belong
to serviceTypeID = (1,2)
I want that record to be retrived only if
there's an existing record for that orderNo in
Reviewed table
and if that orderNo doesn't have tracking type of id (0,7,1) in tracking table
So basically based on above requirements the result should look like
OrderNo CategoryID StationID
100 1 3
200 2 5
select DISTINCT top 10000 o.orderNo , o.categoryID , o.serviceTypeid
,o.countrtId , Tracking.countryId
from Order o
join Tracking on o.orderNo = Tracking.orderNo
where
(o.CategoryID in (1 ) and o.countryId = Tracking.countryId
and
exists (select 1
from tracking t
where t.orderNo = o.orderNo and t.countryId =
o.countryId
)
)
OR
(o.categoryID in (select id from Category where ServiceTypeid in (7,8) and
ID not in (56 , 65)
) and
exists (select 1
from Reviewed r
where r.orderNo = o.orderNo
)
)
AND not exists
( select 1
from tracking t
WHERE T.orderNo = o.orderNo
and t.TrackingTypeID in (0 , 7 ,25))
That query seems to return only orders with ID 1 and even if it's have a trackingTypeID = 0,7,25
You could use exists and boolean logic:
select o.*
from orders o
where
(
category_id = 1
and exists (select 1 from tracking t where t.order_no = o.order_no and t.country_id = o.country_id)
)
or (
category_id = 2
and exists (select 1 from reviewed r where r.order_no = o.order_no)
)
Based on your conditions, you can use boolean logic with exists:
select o.*
from orders o
where (o.categoryid = 1 and
exists (select 1
from tracking t
where t.orderno = o.orderno and t.CountryID = o.CountryID
)
) or
(o.categoryid = 2 and
exists (select 1
from reviewed r
where r.orderno = o.orderno
)
) ;
According to your conditions this query will give results accordingly:
Select o.OrderNo,o.CategoryID,o.CountryID as StationID
from Order o
inner join Tracking t on t.OrderNo = o.OrderNo and t.CountryID = o.CountryID
where o.CategoryID = 1 or (o.CategoryID = 2
and exists (Select * from Reviewed where OrderNo = o.OrderNo))

SQL Server : how to select the rows in a table with the same value on a column but some exact values on another column for the grouped rows

I have this table with some sample data:
Supplier_ID Product_ID Stock
-----------------------------
1 272 1
1 123 5
1 567 3
1 564 3
2 272 4
2 12 3
2 532 1
3 123 4
3 272 5
I want to check the suppliers that have both products: 272 and 123, so the result would be like:
Supplier_ID
-----------
1
3
You can use GROUP BY and HAVING:
SELECT Supplier_ID
FROM your_tab
WHERE Product_ID IN (272, 123)
GROUP BY Supplier_ID
HAVING COUNT(DISTINCT Product_ID) = 2;
LiveDemo
Try this code:
SELECT A.Supplier_ID FROM
(SELECT Supplier_ID FROM Your_Table WHERE Product_ID = 272) AS A
INNER JOIN
(SELECT Supplier_ID FROM Your_Table WHERE Product_ID = 123) AS B
ON A.Supplier_ID = B.Supplier_ID
This is how it works using set operations. IMHO a too little used feature of databases.
select Supplier_ID from table1 where product_id=272
intersect
select Supplier_ID from table1 where product_id=123
it produces as well
Supplier_ID
1
3
By the way a distinct is not needed due to intersect delivers distinct rows.
http://sqlfiddle.com/#!6/13b11/3
Try This Code: By Using Row_number()
;WITH cte
AS (SELECT *,
Row_number()
OVER(
partition BY [Supplier_ID]
ORDER BY [Supplier_ID]) AS rn
FROM #Your_Table
WHERE Product_ID IN ( 272, 123 ))
SELECT DISTINCT Supplier_ID
FROM cte
WHERE rn > 1
OUTPUT:
Supplier_ID
1
3

sql query to get data group by customer type and need to add default value if customer type not found

I have a table "Customers" with columns CustomerID, MainCountry and CustomerTypeID.
I have 5 customer types 1,2,3,4,5 .
I want to count number of customers of each country according to customer type. I am using the following query:
select count(CustomerID) as CustomerCount,MainCountry,CustomerTypeID
from Customers
group by CustomerTypeID,MainCountry
But some countries not have any customers, under type 1,2,3,4 or 5.
So I want to put a default value 0 for if customer type is not exist for that country.
Currently it is giving data as follows :-
CustomerCount MainCountry CustomerTypeID
5695 AU 1
525 AU 2
12268 AU 3
169 AU 5
18658 CA 1
1039 CA 2
24496 CA 3
2259 CA 5
2669 CO 1
10 CO 2
463 CO 3
22 CO 4
39 CO 5
As "AU" not have type 4 so I want a default value for it.
You should JOIN your table with a table with TypeId's. In this case
select count(CustomerID) as CustomerCount,TypeTable.MainCountry,TypeTable.TId
from
Customers
RIGHT JOIN (
select MainCountry,TId from
(
select Distinct MainCountry from Customers
) as T1,
(
select 1 as Tid
union all
select 2 as Tid
union all
select 3 as Tid
union all
select 4 as Tid
union all
select 5 as Tid
) as T2
) as TypeTable on Customers.CustomerTypeID=TypeTable.TId
and Customers.MainCountry=TypeTable.MainCountry
group by TypeTable.TId,TypeTable.MainCountry
Select Country.MainCountry, CustomerType.CustomerTypeId, Count(T.CustomerID) As CustomerCount
From (Select Distinct MainCountry From Customers) As Country
Cross Join (Select Distinct CustomerTypeId From Customers) As CustomerType
Left Join Customers T
On Country.MainCountry = T.MainCountry
And CustomerType.CustomerTypeId = T.CustomerTypeId
-- Edit here
And T.CreatedDate > Convert(DateTime, '1/1/2013')
-- End Edit
Group By Country.MainCountry, CustomerType.CustomerTypeId
Order By MainCountry, CustomerTypeId
Try that:
with cuntry as (
Select Distinct MainCountry From Customers
),
CustomerType as (
(Select Distinct CustomerTypeId From Customers
),
map as (
select MainCountry, CustomerTypeId from cuntry,CustomerType
)
select count(CustomerID) as CustomerCount,a.MainCountry,a.CustomerTypeID
from
map a left join Customers b on a.CustomerCount=b.CustomerCount and a.CustomerTypeID=b.CustomerTypeID

select max value from a table looking for description in another table

i have 3 tables
Buyer
buyer_id | name
50 |Joe
60 |Astor
70 |Cloe
Item
item_id | description
1 | iphone
2 | ipod
3 | imac
Item_Sold
buyer_id | item_id
50 | 1
50 | 2
60 | 1
60 | 3
70 | 1
70 | 2
70 | 3
I want to find out the description of the best-selling item, in this case:
Best-Selling
iphone
SELECT description AS Best_Selling
FROM item
WHERE item_id = (SELECT item_id FROM( SELECT item_id ,COUNT(*) as num_items
FROM Item_Sold
GROUP BY item_id
ORDER BY num_items DESC
LIMIT 1
)z
)
See SQL FIDDLE
This answer is not totally correct . If two items have same sale amount then it will return only one of them.
This query will give all item id decription whose sale is maximum i.e. when two or more item id have equal amount of sale....
;WITH CTE1(Id,Counts) as
(
SelectItem_Id,COUNT(buyer_id ) AS C FROM T GROUP BY ID
)
Select Item.Description from CTE1 A inner join
(Select MAX(Counts) AS MaxCount FROM CTE1 ) b on a.Counts=b.MaxCount
inner join
Item on Item.Item_Id=a.Item_Id
If Common table Expression Not Work you Can Try Like this....
Select Item.Description from (Select Item_Id,COUNT(buyer_id ) AS Counts FROM item_sold GROUP BY Item_Id) A inner join
(Select MAX(Counts) AS MaxCount FROM
(
Select Item_Id,COUNT(buyer_id) AS Counts
FROM item_sold GROUP BY Item_Id) v
) b
on a.Counts=b.MaxCount
inner join
Item on Item.Item_Id=a.Item_Id
SQL Fiddle Demo
Here Is the Liknk of Fiddle the case i m talknig about....it give all description who have maximun sale....
Case Sql Fiddle Demo
select description as "Best-Selling"
from (select a.item_id, b.description, count(*) count
from Item_Sold a,Items b
where a.item_id = b.item_id
group by a.item_id ) temp
where count = (select max(count)
from (select a.item_id, count(*) count
from Item_Sold a,Items b
where a.item_id = b.item_id
group by a.item_id ) temp1)
pl-sql:
select description as "Best-Selling"
from item
where item_id in (
select item_id from (
select item_id, count(item_id) as item_count
from item_sold
group by item_id)
where item_count = (
select max(item_count) from (
select item_id, count(item_id) as item_count
from item_sold
group by item_id)
)
)

Group By by hiding a column - TSQL

I have a table structure
Table1
ID Hours Qty ProductID
1 2 1 100
1 3 5 200
2 6 6 100
2 2 2 200
If productid is (1,2,3) then i need sum ( Qty * Hours),If productid in (200,300,400,500) then i need sum(qty).
I have written a code like this
select ID,case when productid in (1,2,3) then
SUM( qty * hrs)
when productid in (100,200,300) then SUM( qty ) end result1
from Prod group by id ,productid
but i don't want to group by productid,i would like to pass it in "IN clause".How to achieve it.
Move the SUM() outside of the CASE WHEN statement.
SELECT
ID,
SUM(case when productid in (1,2,3) then qty * hrs
when productid in (100,200,300) then qty
end) result1
FROM
Prod
GROUP BY
ID
Assuming you want all columns plus the result of your query, you can do this:
select p.*, aux.result
from Prod p
inner join (select ID,case when productid in (1,2,3) then SUM( qty * hrs)
when productid in (100,200,300) then SUM( qty )
end as result
from Prod group by id ,productid) aux on aux.id = p.id