Update on total field - mysql

i've a problem for a table update. follow table structure:
Table1
tableid
...
...
productID_1
productID_2
productID_3
Table2
productID
Total
I've to totalize each product in table2.
For example:
SELECT COUNT(*) as tot, ProductID_1 FROM Table1 GROUP Table1
then the UPDATE table2 SET total =..??? (how can i do) WHERE productID_1 = ....
Hope you can help me.
Thank you

Your options in terms of simplifying the query greatly depend on the product and version you are using. However, a solution that should work in most databases would be:
Update Table2
Set Total = (
Select Count(*)
From (
Select productId_1 As ProductId From Table1
Union All Select productId_2 From Table1
Union All Select productId_3 From Table1
) As Z
Where Table2.ProductId = Z.ProductId
Group By ProductId
)
A big reason this query is cumbersome is that the data in Table1 is not normalized. Instead you should consider a structure for Table1 like:
Create Table Table1 (
TableId <datatype> not null
, ProductId <datatype> not null
, Constraint PK_Table1 Primary Key ( TableId, ProductId )
)

You can store the first results in a temp table/table variable (if the DB you are using supports it). For instance, in SQL Server, you can do:
declare #t table
(
key int,
cnt int
)
insert into #t (key, cnt)
select count(*) as tot, ProductID_1 from Table1 ...
If ProductID_2 and ProductID_3 are in the same table, you can union the results.
Then, insert into table 2:
insert into table2 (productID, Count)
select key, cnt from #t

REPLACE INTO table2
SELECT COUNT(*) as total, ProductID
FROM Table1
GROUP Table1.ProductID

Related

I want to write a mySQL SELECT query that eliminates rows that have duplicate values in one column

In mySQL
SELECT DISTINCT uID FROM table
returns a recordset with a single uID column where duplicate values are filtered out.
What I'm looking for is something like
SELECT * FROM table (and the uID column is distinct)
that is, where all columns are returned IF the uID value is DISTINCT
edit: here is the full table structure as requested
CREATE TABLE yourTable (
ID int(10) NOT NULL auto_increment,
studyID int(10),
uID varchar(50),
---
PRIMARY KEY (ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
On MySQL 8+, we can use COUNT here as an analytic function:
WITH cte AS (
SELECT *, COUNT(*) OVER (PARTITION BY uID) AS cnt
FROM yourTable
)
SELECT *
FROM cte
WHERE cnt = 1;
On earlier versions of MySQL, we can use exists logic, provided there exist another column which is always unique for each record. Assuming that such an id column exist, we can try:
SELECT *
FROM yourTable t1
WHERE NOT EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.uID = t1.uID AND t2.id <> t1.id);

Creating a View that returns the first occurrence of a value

I'm trying to create a view that returns the first occurrence of a value.
I have two tables
First table:
sID | dt
12 | DateTimeValue1
12 | DateTimeValue2
second table:
S_ID
12
I want the view to join both tables and give me the first occurance of S_ID (in this case DateTimeValue1)
How can I accomplish this?
More Info:
in table 1 I have two columns sID and dt. Values for these columns look like this:
sID: 1 dt: 2014-06-12
sID: 1 dt: 2014-06-13
sID 1 dt: 2014-06-14 etc...
I want to join the two tables in my view so that
where S_ID matches sID it returns the first value (in this case 2014-06-12)
Sorry for any confusion!
Here's what I got so far:
This is what I got so far:
CREATE VIEW view_name AS
SELECT [S_ID]
FROM table1
LEFT JOIN table2
ON table1.[S_ID]=table2.sID;
You could do something like : http://sqlfiddle.com/#!3/66ee02/1
create view theview as
select
t1.s_id, min(dt) dt
from
table1 t1 inner join
table2 t2 on t1.s_id = t2.s_id
group by
t1.s_id
In MS SQL Server you can select the first row of table1 and join it with table2 in a view like this:
create view view_name
as
select table1.*,table2.*
from table2
inner join
(select top 1 *
from table1
order by table1.what_ever_field) as table1
on table2.id = table1.id
This works well if table2 has a foreign key to table1.
If they are independent tables with no foreign keys You can do this:
create view view_name
as
select table1.*,table2.*
from (select top 1 * from table2 order by table2.field1) as table2
,
(select top 1 * from table1 order by table1.field1) as table1
Please try :
select t1.sID,min(t1.dt) from first_table t1, second_table t2 where t1.sID=t2.sID group by t1.sID
I tried same with below code in sybase and it worked well.
create table #temp1
(sID int,dt date)
create table #temp2
(sID int)
insert into #temp1
select 12,getdate()
insert into #temp1
select 12,getdate()
insert into #temp1
select 12,getdate()
insert into #temp2
select 12
insert into #temp1
select 13,getdate()
insert into #temp2
select 13
insert into #temp1
select 14,getdate()
insert into #temp1
select 14,getdate()
insert into #temp2
select 14
select * from #temp1
select * from #temp2
select t1.sID,min(t1.dt) from first_table t1,
second_table t2
where t1.sID=t2.sID
group by t1.sID

select from table based on select distinct from another table

the case is that I need to select a field distinct from table1 (no duplicates) and use the result as a key to select from another table2. And I need this to be in one query. Is this possible?!
table1: hID, hName, hLocation
table2: hID, hFrom, hTo, hRate, hRoomType, hMeals
I want to correct version of this query:
SELECT
*
FROM
table1
JOIN (
DISTINCT
hID
FROM
table2
WHERE
hRoomType = Double Room
ON table1.hID = table2.hID)
expected result: all hotels that offer Double Room thanks much –
thanks for help!
Your question is quite vague and confusing. Is this what you are looking for:
SELECT hID, name, location
FROM table2
INNER JOIN table1
ON table1.hID = table2.hID
GROUP BY table2.hID;
Here is a skeleton to achieve this:
SELECT
* -- Don't forget to list the requested fields instead of using `*`!
FROM (
-- This is the distinct list from table1
SELECT DISTINCT
id
FROM
table1 T1
) DT1
INNER JOIN table2 T2
ON T1.id = T2.reference_to_t1_id
Another solution if you don't want to retrieve any columns from table1:
SELECT
* -- Don't forget to list the requested fields instead of using `*`!
FROM
table2 T2
WHERE
-- Sais that get all record from table2 where this condition matches
-- at least one record
EXISTS (
SELECT 1 FROM table1 T1 WHERE T1.id = T2.reference_to_t1_id
)
For your tables and question
SELECT
hID, hName, hLocation
FROM
table1 T1
WHERE
EXISTS (
SELECT 1 FROM
table2 T2
WHERE
T1.hID = T2.hID
AND T.hRoomType = 'Double' -- Assuming that this is the definition of double rooms
)

Mysql delete older duplicates

I've got table with this data
id, archive id, ean, index, date, (...)
I've got some items with same archive id, same ean, but different index.
So in this case, I want to delete older (basing on date) item, so result will be that for each combination archive_id/index there will be no more than 1 result.
The following (untested) should work:
DELETE FROM someTable WHERE EXISTS ( SELECT id FROM someTable AS subqTable WHERE
subqTable.id = someTable.id
AND subqTable.ean = someTable.ean
-- and other equality comparisons
AND subqTable.date AFTER someTable.date)
DELETE duplicates.*
FROM _table
JOIN _table AS duplicates
ON (_table.archive_id = duplicates.archive_id AND _table.index = duplicates.index)
WHERE duplicates.date < _table.date;
delete t1
from your_table t1
left join
(
select archive_id, ean, min(date) as mdate
from your_table
group by archive_id, ean
) t2 on t1.archive_id = t2.archive_id
and t1.ean = t2.ean
and t1.date = t2.mdate
where t2.mdate is null

Delete records from a table where < max number for a field and keep highest number

I know this sounds rather confusing but I'm at a loss how to explain it better. I have a table simplified below:
DB Type ID
================
Table1 1
Table1 2
Table1 3
Table1 4
Table1 5
Table2 6
Table2 7
Table2 8
Table2 9
Table2 10
what i am trying to achieve is to basically clean out this table but keep the record with the highest ID for each DB Type if that makes sense - so in this case it would be (Table1,5) and (Table2,10) with all other records being deleted. Is it possible to do this exclusively through MySQL?
*EDIT***
Answer thanks to tips from Yogendra Singh
DELETE FROM MyTable WHERE ID NOT IN (SELECT * FROM (SELECT MAX(ID) from MyTable GROUP BY DB Type) AS tb1 ) ORDER BY ID ASC
TRY selecting the max ID group by db_type first and then use it as sub query with not in.
DELETE FROM MyTable
WHERE ID NOT IN
(SELECT ID FROM
(SELECT MAX(ID) AS ID from MyTable GROUP BY DB Type) AS tb1
)
EDIT:
DELETE FROM MyTable
HAVING MAX(ID) > ID;
delete your_table
from
your_table left join
(select max(id) max_id from your_table group by type) mx
on your_table.id=mx.max_id
where mx.max_id is null
Subquery returns the maximum id for every type, and those are the values to keep. With an left join i'm selecting all the rows from your table that don't have an in in max_ids, and those are the rows to delete. This will work only if id is primary key, otherwise we have to join also the type.
Is the combination DB Type - ID unique?
If so, you can attack this in two stages:
Get only the rows you want
SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable
GROUP BY [DB Type]
Delete the rest (Wrapping the previous statement into a more complicated statement; don't mean that)
DELETE FROM YourTable
FROM
YourTable
LEFT JOIN
(SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable GROUP BY [DB Type]) DontDelete
ON
YourTable.[DB Type]=DontDelete.[DB Type] AND
YourTable.ID=DontDelete.MaxID
WHERE
DontDelete.[DB Type] IS NULL
DELETE FROM MyTable del
WHERE EXISTS (
(SELECT *
FROM MyTable xx
WHERE xx."db Type" = del."db Type"
AND xx.id > del.id
);
delete from my_Table
where Day in (select MAX(day) d from my_Table where id='id')