Mysql - Fetch data from EXISTS (SELECT..) statement aswell - mysql

I have a mysql query that returns user_name and sess_start from sess_active table if user_name exists in sess_active_tmp table.
Query below for above is working as inteded, but I also would like to retrieve data from sess_active_tmp table aswell. Since I execute another SELECT statement in EXISTS part, shouldn't I be able to retrieve data of this statement aswell?
Working query:
SELECT sess_main.user_name,
sess_main.sess_start
FROM sess_active AS sess_main
WHERE ( sess_main.user_name = 'testuser'
AND sess_main.sess_stop IS NULL )
AND EXISTS (SELECT user_name
FROM sess_active_tmp AS sess_temp
WHERE sess_temp.user_name = 'testuser'
AND sess_temp.sess_start =
sess_main.sess_start
AND sess_temp.sess_stop IS NULL)
Query I am trying to get it work;
SELECT sess_main.user_name,
sess_main.sess_start,
sess_temp.upload_byte,
sess_temp.download_byte,
FROM sess_active AS sess_main
WHERE ( sess_main.user_name = 'testuser'
AND sess_main.sess_stop IS NULL )
AND EXISTS (SELECT user_name
FROM sess_active_tmp AS sess_temp
WHERE sess_temp.user_name = 'testuser'
AND sess_temp.sess_start =
sess_main.sess_start
AND sess_temp.sess_stop IS NULL)
I also added sess_temp.upload_byte, sess_temp.download_byte to sess_temp select statement but it also doesn't work.
Is it only achievable with JOIN and if yes would it decrease performance? since this query will run like 2-3k times(users) every 2 minutes.
Thanks in advance.
EDIT: Query below does what I want to achieve but I have performance concerns, is it the best way to achieve what I want to do?
SELECT sess_main.user_name,
sess_main.sess_start,
sess_temp.upload_byte,
sess_temp.download,
FROM sess_active AS sess_main
INNER JOIN sess_active_tmp sess_temp
ON ( sess_temp.user_name = sess_main.user_name
AND sess_temp.sess_start = sess_main.sess_start
AND sess_temp.sess_stop IS NULL )
WHERE ( sess_main.user_name = 'testuser'
AND sess_main.sess_stop IS NULL )
AND EXISTS (SELECT user_name
FROM sess_active_tmp AS sess_temp
WHERE sess_temp.user_name = 'testuser'
AND sess_temp.sess_start = sess_main.sess_start
AND sess_temp.sess_stop IS NULL)

Related

SQL query to select a value based on certain criteria

I have the following data in my Database:
Id MachineName CategoryName CounterName InstanceName RawValue
11180 SERVER64 Process ID Process w3wp#2 2068
11180 SERVER64 Process Working Set w3wp#2 9310208
Now I want to achieve that if I find the value '2068' for the "ID Process" Countername then I want to retrieve the Working Set RawValue. So based on the value of ID Process I now the [InstanceName] = w3wp#2 and therefore I want the value to retrieve = 9310208
Now I tried different SQL queries:
SELECT *
FROM [dbo].[LoadTest]
WHERE [LoadTestRunId] = '11180' and [CategoryName] = 'Process' and [InstanceName] like 'w3wp%'
But I need a filter. Can anyone guide me into the right direction?
This here will help you. I used variable because you need to find a specific ID
SQL Code
declare #myt table (id int,MachineName nvarchar(50),CategoryName nvarchar(50),CounterName nvarchar(50),InstanceName nvarchar(50),RawValue int)
insert into #myt
values
(11180 ,'SERVER64','Process','ID Process','w3wp#2',2068),
(11180 ,'SERVER64','Process','Working Set','w3wp#2',9310208)
declare #FindID int
Set #FindID = 2068;
with IdProcess as (
Select * from #myt
where RawValue = #FindID and CounterName = 'ID Process'
)
Select a.ID,a.MachineName,a.CategoryName,b.CounterName,a.InstanceName,b.RawValue from IdProcess a
inner join #myt b on a.InstanceName = b.InstanceName and b.CounterName='Working Set'
SQL Code without variable based on ID and InstanceName
with IdProcess as (
Select * from #myt
where CounterName = 'ID Process'
)
Select a.ID,a.MachineName,a.CategoryName,b.CounterName,a.InstanceName,b.RawValue from IdProcess a
inner join #myt b on a.id = b.id and a.InstanceName = b.InstanceName and b.CounterName='Working Set'
SQL Code with CategoryName filter
with IdProcess as (
Select * from #myt
where CounterName = 'ID Process' and CategoryName = 'Process'
)
Select a.ID,a.MachineName,a.CategoryName,b.CounterName,a.InstanceName,b.RawValue from IdProcess a
inner join #myt b on a.id = b.id and a.InstanceName = b.InstanceName and b.CounterName='Working Set'
where b.CategoryName = 'Process'
Result
This will execute.
Select * from (SELECT ROW_NUMBER() OVER(PARTITION BY LoadTestRunId ORDER BY LoadTestRunId DESC) as row,*
FROM [dbo].[LoadTest]) t1 where row=1
with your where clause
Select * from (SELECT ROW_NUMBER() OVER(PARTITION BY LoadTestRunId ORDER BY LoadTestRunId DESC),*
FROM [dbo].[LoadTest]) t1 where t1=1
and [LoadTestRunId] = '11180' and [CategoryName] = 'Process' and [InstanceName] like 'w3wp%'

Does MySQL support "if not exists"?

I have a database where i put some societies and their employees. The thing is that two societies can have an employe with the same name (but they are different person). So when I want to insert an employe (stagiaire) I try to check if it exists for this society.
Here is my query :
INSERT INTO stagiaire(Nom,Email,Telephone,IDSociete )
VALUES('Paul','ppk#mail.fr','0000000000','7' )
WHERE(SELECT stagiaire.ID FROM stagiaire
LEFT JOIN societe ON stagiaire.IDSociete = societe.ID
WHERE stagiaire.Nom = 'Paul' AND societe.NomSoc = 'PachaKebab') NOT EXISTS
Heres 'Paul' already exists in the society 'Promoplantes' and I have another 'Paul' in the society 'PachaKebab' (ID = 7) the one I try to insert.
I tried few things like IF NOT EXISTS the my INSERT query (between begin/end) but it seems like phpMyAdim (SQL Server that i use) can't unserstand the IF NOT EXISTS or NOT EXISTS code.
Is that true ? Or do I have an error in my code that I dont see ?
The correct syntax is SELECT ... FROM ... WHERE NOT EXISTS
INSERT INTO stagiaire(Nom,Email,Telephone,IDSociete )
SELECT 'Paul','ppk#mail.fr','0000000000','7'
FROM stagiaire
WHERE NOT EXISTS(SELECT stagiaire.ID FROM stagiaire
LEFT JOIN societe ON stagiaire.IDSociete = societe.ID
WHERE stagiaire.Nom = 'Paul' AND societe.NomSoc = 'PachaKebab')
LIMIT 1;
Use not exists and restructuring your query
INSERT INTO stagiaire(Nom,Email,Telephone,IDSociete )
Select Nom,Email,Telephone,IDSociete
From stagiaire s
WHERE NOT EXISTS(SELECT 1 from societe x
WHERE x.id = s.IDSociete)
And s.IDSociete = 7

SQL Statement for gouping messages

I have the following code and I'm trying to group the messages
Here is a picture of database table and how the groups should be
and here is the SQL statement
SELECT a.* FROM `user_messages` `a`
JOIN (
SELECT `sender`, MAX(`id`) `last_id` FROM `user_messages` WHERE `receiver` = '1' GROUP BY `sender`
) `b`
ON `a`.`sender` = `b`.`sender` AND `a`.`id` = `b`.`last_id`
WHERE `a`.`receiver` = '1'
ORDER BY `id` DESC
OUTPUT:
I want to get somehow the last record where "receiver" is not my id, but "sender" is and name receiver column as "id" or something.
...so what i want is following result:
id | msg
13852 123
48 Hello!
17 321
Here is a fiddle: http://sqlfiddle.com/#!9/e06d57/3/0
To map my generic answer to your particular use case (using example 1):
SELECT receiver AS id, msg
FROM user_messages outerTable
WHERE NOT EXISTS
( SELECT *
FROM user_messages innerTable
WHERE innerTable.sender = outerTable.sender
AND innerTable.receiver = outerTable.receiver
AND innerTable.added > outerTable.added
)
AND sender = 1
This is a very common use case. There are several ways to write this code. Depending on the SQL engine used, they will be of different speeds.
I will use fairly generic column names. Tweak as needed.
SELECT common_id, msg
FROM myTable outerTable
WHERE NOT EXISTS
( SELECT *
FROM myTable innerTable
WHERE innerTable.common_id = outerTable.common_id
AND innerTable.time > outerTable.time
)
Please note that if there are two rows with identical common_id and time columns, then both will show up in the output. You can replace the > with >= to hide both of those rows.
The other common approach is kind of difficult to make sense of, but here goes. Notice the similarities to the NOT EXISTS approach.
SELECT outerTable.common_id, outerTable.msg
FROM myTable outerTable
LEFT JOIN myTable innerTable
ON innerTable.common_id = outerTable.common_id
AND innerTable.time > outerTable.time
WHERE innerTable.common_id IS NULL
According to your description, you seem to want something like this:
select um.receiver as id, um.msg
from user_messages um
where um.sender = 1 and
um.id = (select max(um2.id)
from user_messages um2
where um2.msg = um.msg and um2.receiver <> 1 and um.sender = 1
);
It doesn't produce the desired output, but that is because the output is inconsistent with the text description.

mySQL Query get record that dont match

I have an sql query that I wish to add another condition to but I cant seem to get it work. The query is simple enough:
SELECT DISTINCT monthly_returns.company_id
FROM monthly_returns, paidreturns
WHERE monthly_returns.company_id = paidreturns.company_id
AND paidreturns.month = '$cdate'
AND paidreturns.paid =0
However I wish to get the records also from the monthly_returns that have not record at all in paidreturns for the give date. I know it would be something like this
SELECT *
FROM monthly_returns
WHERE monthly_returns NOT IN (SELECT * FROM paidreturns WHERE paidreturns.month = '$cdate')
paidreturns.paid =0 is where the bill has not been paid, but equally if there is no record for that date in paidreturns then the bill is also not paid.
The schema
paidreturns table
-id
-company_id
-paid
-month
-total
monthly_returns table
-id
-company_id
-wage_totals
-month
Try this:
SELECT
DISTINCT monthly_returns.company_id
FROM
monthly_returns
LEFT JOIN
paidreturns
ON monthly_returns.company_id = paidreturns.company_id
AND monthly_returns.month = paidreturns.month
WHERE
monthly_returns.month = '$cdate'
AND
(
paidreturns.paid = 0
OR
paidreturns.company_id IS NULL
);
Using a LEFT JOIN, you can find all records from monthly_returns, regardless of whether they matched an entry from paidreturns.
Then, by adding paidreturns.company_id IS NULL to the WHERE clause, you include those unmatched entries in your query.
select company_id
from
(
(
SELECT DISTINCT monthly_returns.company_id
FROM monthly_returns, paidreturns
WHERE monthly_returns.company_id = paidreturns.company_id
AND paidreturns.month = '$cdate'
AND paidreturns.paid =0
)
union
(
SELECT company_id
FROM monthly_returns
WHERE monthly_returns NOT IN (SELECT * FROM paidreturns WHERE paidreturns.month = '$cdate'
)
) as x

sql UNION breaks query

Query :
(
SELECT
upd.uid,
upd.update_id,
upd.update,
upd.date,
upd.type,
upd.total_likes,
upd.total_comments,
upd.deleted,
usr.username AS `username`,
usr.profile_picture AS `profile_picture`
,(
SELECT
COUNT(lik.id)
FROM
likes as lik
WHERE
upd.update_id = lik.item_id
AND
lik.uid = 118697835834
AND lik.type=0
) as liked_update,
(
SELECT
COUNT(fav.id)
FROM
favorites as fav
WHERE
upd.update_id = fav.item_id
AND
fav.uid = 118697835834
AND fav.type=0
) as favorited_update
FROM
updates AS upd
LEFT JOIN
users AS usr
ON upd.uid = usr.uid
WHERE
upd.deleted=0
AND
(
upd.uid=118697835834
OR EXISTS
(
SELECT *
FROM
subscribers AS sub
WHERE
upd.uid = sub.suid
AND sub.uid = 118697835834
)
)
)
UNION
(
SELECT
topic.uid,
topic.tid,
topic.title,
topic.body,
topic.total_likes,
topic.total_replies,
topic.views,
topic.date,
usr.username AS `username`,
usr.profile_picture AS `profile_picture`
,(
SELECT
COUNT(lik.id)
FROM
likes as lik
WHERE
topic.update_id = lik.item_id
AND
lik.uid = 118697835834
AND lik.type=1
) as liked_update,
(
SELECT
COUNT(fav.id)
FROM
favorites as fav
WHERE
topic.update_id = fav.item_id
AND
fav.uid = 118697835834
AND fav.type=1
) as favorited_update
FROM
topics AS topic
LEFT JOIN
users AS usr
ON topic.uid = usr.uid
WHERE
topic.deleted=0
AND
(
topic.uid=118697835834
OR EXISTS
(
SELECT *
FROM
subscribers AS sub
WHERE
topic.uid = sub.suid
AND sub.uid = 118697835834
)
)
)
ORDER BY date DESC
I have added the UNION ( SELECT ) and the query takes forever to load and finally it stops returning a blank page...
removing UNION ( SELECT ) works fine...
OK after all the comments can you please say what changes you made to get the script working.
In light of your comment about the data from two tables being in the same columns that is because you have told the engine to do that by using UNION. If you want them in seperate columns you will need to place Nulls in between:
SELECT
upd.uid,
upd.update_id,
upd.update,
upd.date,
upd.type,
upd.total_likes,
upd.total_comments,
upd.deleted,
null AS `topicuid`,
null AS `topictid`,
null AS `topictitle`,
null AS `topicbody`,
null AS `topictotal_likes`,
null AS `topictotal_replies`,
null AS `topicviews`,
null AS `topicdate`,
usr.username AS `username`,
usr.profile_picture AS `profile_picture`,
(SELECT COUNT(lik.id) FROM likes as lik WHERE upd.update_id = lik.item_id AND lik.uid = 118697835834 AND lik.type=0) as liked_update,
(SELECT COUNT(fav.id) FROM favorites as fav WHERE upd.update_id = fav.item_id AND fav.uid = 118697835834 AND fav.type=0) as favorited_update
FROM
......
UNION ALL
SELECT
null AS `upd.uid`,
null AS `upd.update_id`,
null AS `upd.update`,
null AS `upd.date`,
null AS `upd.type`,
null AS `upd.total_likes`,
null AS `upd.total_comments`,
null AS `upd.deleted`,
topic.uid,
topic.tid,
topic.title,
topic.body,
topic.total_likes,
topic.total_replies,
topic.views,
topic.date,
usr.username AS `username`,
usr.profile_picture AS `profile_picture`,
(SELECT COUNT(lik.id) FROM likes as lik WHERE topic.update_id = lik.item_id AND lik.uid = 118697835834 AND lik.type=1) as liked_update,
(SELECT COUNT(fav.id) FROM favorites as fav WHERE topic.update_id = fav.item_id AND fav.uid = 118697835834 AND fav.type=1) as favorited_update
You might need to do a bit more work on the column names but you should get there. You should read up on what the UNION operator actually does to two or more queries.
When you use UNION you have to have exact same results "column format, names,..." so you have at top of query upd.total_comments as total_comments, and bottom you have topic.total_replies as total_replies those are different names. hope you understand what i try to explain, if not visit here where it explains better.