Finding rows based on Conflicting conditions - mysql

i have a table filled with mails messages that contains all mails from certain domains. columns are - domain_name, subject and receipt.
i want to find all the domains in my database that have sent a 'welcome' mail and a receipt through out time.
in order for a mail to be a receipt :
g.receipt != '{}'
in order for a mail to be a 'Welcome' mail:
g.subject regexp 'Welcome'
the problem is that the two conditions create a conflict. i can't search for both of them because i will have 0 results. a single mail can be a Welcome OR Receipt.
but i need to find domains who sent both through out time.
all i could do is narrowing the possibilities with this:
select
*
from
(select
if(g.receipt != '{}', #R:=1, #R:=0) As Receipt,
if(g.subject regexp 'Welcome', #M:=1, #M:=0) AS Welcome,
g.domain_name,
g.subject,
g.receipt
from
table as g
) as B
where
(#M:= 1 and #R:=0) or (#R:=1 and #M:=0)
group by domain_name, Welcome, Receipt
This code gives me all domains that sent a 'Welcome' Or a receipt. (i have other type of messages in the database). is there any way to code this so i wont need to find them with my eyes?
Thank you, i use mysql.

This should give you the results you need. Note that I've called your table domains due to table being a reserved keyword.
select distinct domain_name from domains welcome_messages
where
subject like '%Welcome%'
and exists
(
select * from domains receipts
where
receipts.receipt != '{}'
and welcome_messages.domain_name = receipts.domain_name
)
Here's a sqlfiddle of the script above.

Related

Compare results of two SQL queries?

So I'm using SAP Business One application and using B1 validation configuration to give error messages. The main goal of this is where it compares addresses from the BP master data address and the address from the sales order/delivery order address.
So here's the code for the first query which is for the open sales orders only:
SELECT dbo.ORDR.DocNum, dbo.ORDR.DocStatus, dbo.RDR12.StreetS, dbo.RDR12.BlockS, dbo.RDR12.CityS, dbo.RDR12.ZipCodeS, dbo.RDR12.StateS, dbo.RDR12.CountryS
FROM dbo.ORDR INNER JOIN
dbo.RDR12 ON dbo.ORDR.DocEntry = dbo.RDR12.DocEntry
WHERE (dbo.ORDR.DocStatus = 'o')
Heres the code for the second query from the business partner data. This contains all addresses and data
SELECT dbo.CRD1.Street, dbo.CRD1.Address, dbo.CRD1.Block, dbo.CRD1.ZipCode, dbo.CRD1.City, dbo.CRD1.Country, dbo.CRD1.State
FROM dbo.CRD1 INNER JOIN
dbo.OCRD ON dbo.CRD1.CardCode = dbo.OCRD.CardCode
So now I'm hoping to be able to create an SQL condition where it compares these two. Like for example (pseudo code):
if(street != street.s)
begin
if(zip != zip.s)
begin
if(country != country.s).....
begin
Select 'error' for browse
else
select 'passed' for browse
Overall I'm just trying to compare the 2 queries with ONLY open sales orders/delivery orders.
So I'm trying to get it to trigger the error message.
The problem being, I don't know how to pull the values from each one since there's tons of addresses to compare from and I can't just hard code it in.
For example the inputted data is 91234 for zipcode, and zipcode.s is 92134 which is obviously different and would give the error message.

What is the order of data comparison in the database for SELECT by column A OR column B

I have a query where I need to fetch a row by 1) comparing by old_email, and if not found then 2) by comparing the email column.
I need to make sure that the first check is always by an old email, and the second check is by the new email if the old one wasn't found.
I know that I can't use set because the comparison order is not guaranteed, e.g.
SELECT * FROM champions WHERE (email IN ('old#example.com', 'new#example.com'))
Will the following code satisfy my needs:
SELECT * FROM champions WHERE (email = 'old#example.com' OR email = 'new#example.com')
A WHERE clause is applied row by row. The result from one row is unaware of the result from another row.
What you seems to be describing is "look for email address X, if not found look for email address Y".
There are a few ways to do that. The following, for example, is a very literal approach to what you described...
SELECT
*
FROM
champions
WHERE
email = 'new#example.com'
UNION ALL
SELECT
*
FROM
champions
WHERE
email = 'old#example.com'
AND NOT EXISTS (SELECT * FROM champions WHERE email = 'new#example.com')
That does literally what you described. Find email address X. Also find email address Y, on the condition that email address X is not present.
That's pretty verbose though, you end up checking for 'X' twice... It's better to think in a more set based manner.
Find records with email addresses X or Y
Sort them so that records with email address X come first
Pick only the first record
For example...
SELECT
*
FROM
champions
WHERE
email IN ('old#example.com', 'new#example.com')
ORDER BY
CASE WHEN email = 'new#example.com' THEN 1 ELSE 2 END
LIMIT
1

MySQL: Select unique field and return all other columns as well + if specific column is not 0 - return that

I can't figure out how to get this done.
Basically I am making message system, I have this table:
Basically I am trying to print out threads, like every distinct msgfrom is a new thread.
Thread should basically say:
[(Sender Name) (Last Message (ORDER BY id DESC)) ([if at least one
message has msgread=0 then say You have unread messages])
I've tried this so far:
SELECT id, msgfrom, message, date,
IF(msgread='0', 'unread', 'read') AS msr
FROM pmessages WHERE msgto=$userId GROUP BY msgfrom
But that returns:
message from: Username (this is msgfrom 1)
read
message from: Username (this is msgfrom 2)
unread
Even though msgfrom1 has 1 unread message, it says read (I assume it takes first result). So in basic:
SELECT UNIQUE msgrom
ORDER BY id DESC
IF at least ONE msgread = 0
return * + set msgread=0 (unread)
It's a bit hard to explain, sorry if it's a bit unclear.
You can't reliably GROUP your data together as you attempted in the first SQL.
If I understand you correctly, you want to differentiate the posts which are read and unread?
SELECT id
, msgfrom
, message
, date
, CASE WHEN msgread = 0 THEN 'unread' ELSE 'read' AS msgread
FROM pmessages
WHERE msgfrom IN ( SELECT DISTINCT msgfrom
FROM pmessages
WHERE msgto = ?
)
ORDER BY msgfrom ASC
, date DESC
Please make sure you use placeholders in your code (assuming PHP) rather than passing the variable in directly into the query, to prevent SQL Injection.
Let me know how you get on.

Count on work history log

I have a table request:
and a table requesthx:
A single Request can have many log updates by multiple techs. For example, tech1 can create a log for the initial phone contact and add notes in the log section. Then tech2 could take those notes and complete a portion of the job requirement. Tech 3 could also be working on the same job waiting for a scheduled appointment.
If tech3 is logged in, I'd like to display a count of every open ticket for tech3.
What is the best way to accomplish this?
I've completed several ugly queries that had queries running within foreach loops to add to a count variable, but this seems like the really long way to reach a simple count total.
I've tried...
SELECT requesthx.hxID, requesthx.requestID,
requesthx.datetime_gmt, requesthx.log, requesthx.techID, requesthx.status,
COUNT($requestTable.requestID) AS tickets, request.status, requesthx.techID
FROM requesthx
LEFT JOIN request
ON (requesthx.requestID = request.requestID)
WHERE (requesthx.status <> 'closed'
AND request.status = 'open'
AND requesthx.techID = '1')
GROUP BY requesthx.techID;
...on a query that had 5 open tickets with techID = 1. I only receive 1 as the count. Any ideas?
You are correct the database has a way of counting this kind of information.
Select count(*) as "TicketCount"
From requesthx
Where techid=3
And status = "open"
Group by techid
I assume my own value for status fields in both tables
SELECT
`requesthx`.`hxID`
, `requesthx`.`requestID`
, `requesthx`.`datetime_gmt`
, `requesthx`.`log`
, `requesthx`.`techID`
, `requesthx`.`status`
, COUNT(`request`.`requestID`) AS tickets
, `request`.`status`
, `requesthx`.`techID`
FROM
`requesthx`
LEFT JOIN `test`.`request`
ON (`requesthx`.`requestID` = `request`.`requestID`)
WHERE (`requesthx`.`status` ="logged"
AND `request`.`status` ="open"
AND `requesthx`.`techID` =3)
GROUP BY `requesthx`.`techID`;

List specific with a single table

I have following messages table:
I want to list all messages in a inbox like for example,
lets assume I am user number 1 so my inbox should show
me following:
Messages with user 2
Messages with user 3
Messages with user 4
What is the best way to build a query for this?
I've came up with somewhat weird query that looks like: (pseudo code)
SELECT
*
FROM
`message`
WHERE
(`user_id_sender` = 1 AND `user_id_receiver` NOT 1)
OR
(`user_id_sender` NOT 1 AND `user_id_receiver` = 1)
Thank you
That's very simple
SELECT user_id_sender ID,
(SELECT user_id_reciever
FROM messages
WHERE user_id_sender NOT IN(ID)
GROUP BY user_id_reciever
)
FROM message