MySQL using OR in Select Query - when class has been used - mysql

Info: Server version: 5.1.39
Php: 5.4
MySQL / phpMyAdmin
Server: Apache
Code is run via: Server SQL Query (copy & paste in the phpMyAdmin) or in MySQL Workbench or using a custom shopping cart manager.
Exports to: Excel (.csv then to .xlsx for sales reports)
Other: I do use a number of tables for referencing
This is part of a larger SELECT Query I am running. For the sake of brevity I have included only the section I currently need looking at.
Select
T5.orders_id As OrdID,
T3.products_name As ProdName,
<continues>
(select value from /*PREFIX*/orders_total T5 where orders_id = T2.orders_id and class = 'ot_reward_points_discount') As ot_reward_points_discount,
(select value from /*PREFIX*/orders_total T5 where orders_id = T2.orders_id and class = 'ot_reward_points') As ot_reward_points_discount,
<more data queries>
Inner Join /*PREFIX*/orders T5 On (T5.orders_id = T2.orders_id)
<number of joins and final WHERE/DESC>
The results end up with me having 2 columns, the data has not merged. I have been directed in to looking at an OR query so that the 2 will result in the one column. There is no concern with results being overwritten as they 1st select & the 2nd select are from different configs in my cart, 1 predates the other.
Because the SELECT chooses from a class value so it returns in column (not row) data per value I have NO idea how to create the OR query so it returns neatly.
Thank you for your help, please let me know if there is further info I need to supply.

Try to use OR this way :
<continues>
(select value from /*PREFIX*/orders_total T5
where orders_id = T2.orders_id and
(class = 'ot_reward_points_discount' or class = 'ot_reward_points')
) As ot_reward_points_discount,
<more data queries>

Related

Query to find entries and transpose

I've got a machine log available in an SQL table. I can do a bit in SQL, but I'm not good enough to process the following:
In the data column there are entries containing "RUNPGM: Recipe name" and "RUNBRKPGM: Recipe name"
What I want is a view containing 4 columns:
TimeStamp RUNPGM
TimeStamp RUNBRKPGM
Recipe Name
Time Difference in seconds
There is a bit of a catch:
Sometimes the machine logs an empty RUNBRKPGM that should be ignored
The RUNBRKPGM is sometimes logged with an error message. This entry should also be ignored.
It's always the RUNBRKPGM entry with just the recipe name that's the actual end of the recipe.
NOTE: I understand this is not a full/complete answer, but with info available in question as of now, I believe it at least helps give a starting point since this is too complicated (and formatted) to put in the comments:
If Recipe is everything in the DATA field except the 'RUNPGM = ' part you can do somethign similar to this:
SELECT
-- will give you a col for TimeStamp for records with RUNPGM
CASE WHEN DATA LIKE 'RUNPGM%' THEN TS ELSE '' END AS RUNPGM_TimeStamp,
-- will give you a col for TimeStamp for records with RUNBRKPGM
CASE WHEN DATA LIKE 'RUNBRKPGM%' THEN TS ELSE '' END AS RUNBRKPGM_TimeStamp,
-- will give you everything after the RUNPGM = (which I think is the recipe you are referring to)
CASE WHEN DATA LIKE 'RUNPGM%' THEN REPLACE(DATA, 'RUNPGM = ', '' AS RUNPGM_Recipe,
-- will give you everything after the RUNBRKPGM = (which I think is the recipe you are referring to)
CASE WHEN DATA LIKE 'RUNBRKPGM:%' THEN REPLACE(DATA, 'RUNBRKPGM = ', '' AS RUNPGM_Recipe
FROM TableName
Im not sure what columns you want to get the Time Difference on though so I dont have that column in here.
Then if you need to do additional logic/formatting on the columns once they are separated you can put the above in a sub select.
As a first swing, I'd try the following:
Create a view that uses string splitting to break the DATA column into a its parts (e.g. RunType and RecipeName)
Create a simple select that outputs the recipe name and tstamp where the runtype is RUNPGM.
Then add an OUTER APPLY:
Essentially, joining onto itself.
SELECT
t1.RecipeName,
t1.TimeStamp AS Start,
t2.TimeStamp AS Stop
--date func to get run time, pseudo DATEDIFF(xx,t1.TimeStamp, t2.TimeStamp) as RunTime
FROM newView t1
OUTER APPLY ( SELECT TOP ( 1 ) *
FROM newView x
WHERE x.RecipeName = t1.RecipeName
AND RunType = 'RUNBRKPGM'
ORDER BY ID DESC ) t2
WHERE t1.RunType = 'RUNPGM';

SELECT * FROM db1 WHERE db1.table.value = db2.table.value

I'm working with mySQL db and trying to display the correct data for the user. In order to do that I check if the data that I call from one backend is equal to username from another backend like so
SELECT * FROM db1 WHERE db1.table.value = db2.table.value
Names of databases are A and B.
SELECT *
FROM `A.onboardings`
, `B.loginsystem`
WHERE onboardings.sales_email = loginsystem.username
The problem is I get an error A.A.onboardings doesn't exists and A.B.loginsystem doesn't exist pls help :(
You must use this form - from A onboardings
You have to put the backticks in the right pace, or else mysql things your table is called A.onboardings
As seen bleow the needs to be around the database and the table name
And the use of aliases helps to keep even in big queries a good overview and yu have to write less
"SELECT * FROM `A`.`onboardings` a1,`B`.`loginsystem` b1 WHERE a1.sales_email = b1.username"
Try this one( Change the query according to your DB name, table, and matching column name)
SELECT * FROM mydatabase1.tblUsers INNER JOIN mydatabase2.tblUsers ON mydatabase1.tblUsers.UserID = mydatabase2.tblUsers.UserID
The problem is that
`A.onboardings`
is not the same as
A.onboardings
The first is a table reference where there table name has a period in it. The second is for the onboardings table in database A.
In addition, you should be using JOIN!!!
SELECT *
FROM A.onboardings o JOIN
B.loginsystem ls
ON o.sales_email = ls.username;
If you feel compelled to escape the identifies -- which I do not recommend -- then:
SELECT *
FROM `A`.`onboardings` o JOIN
`B`.`loginsystem` ls
ON o.sales_email = ls.username;

Mysql Query for fetching records using single Query from three tables

We have three table
table 1- app ( id , name )
table 2- appPlayer ( id , name )
table 3- appPlayerSession ( id , appId , appPlayerId , version)
my Current query is:
SELECT (select name from app k where k.id= aps.appId) AS appName,version,appId,count(version) FROM appPlayerSession aps GROUP BY appId,version,appName
we need to count the session users for each game with same version, and also woth the object of all users data using single mysql query.
Current Result using my query, but we also need players for each app..
As you havent given your expected result and on basis of your requirement you can do something this.it may be enhanced as per your requirement.
SELECT (select name from app k where k.id= aps.appId) AS appName,version,appId,(select P.name from appPlayer P where P.id=aps.appPlayerid) as appPlayerName, count(version) FROM appPlayerSession aps GROUP BY appId,version,appName,appPlayerName
Also check fiddle as per your requirement created as you havent given any data set and its on my assumption.
http://sqlfiddle.com/#!9/30fe4f/1
New Sql as per your new added requirement-
select X.appname,X.version,X.appid,GROUP_CONCAT(distinct X.appPlayerName order by X.appPlayerName) as Users ,
sum(X.vercount)
from (SELECT (select name from app k where k.id= aps.appId)
AS appName,version,appId,
(select P.name from appPlayer P where P.id=aps.appPlayerid)
as appPlayerName, count(version)as vercount
FROM appPlayerSession aps
GROUP BY appId,version,appName,appPlayerName) X
group by X.appname,X.version,X.appid
New fiddle -http://sqlfiddle.com/#!9/13646c/5
You can use JOIN in sql to connect with multiple tables and fetch result
Below is the format :
SELECT t1.col, 
       t3.col 
FROM   table1 
       JOIN table2 
         ON table1.primarykey = table2.foreignkey 
       JOIN table3 
         ON table2.primarykey = table3.foreignkey 
In your case :
SELECT app.col, 
       appPlayer.col,
appPlayerSession.col 
FROM   app 
       JOIN appPlayer 
         ON app.id = appPlayer.appId
       JOIN appPlayerSession 
         ON appPlayer.id = appPlayerSession.appPlayerId
Hope this is helpful.
One suggestion . It is not a standard to use camelCase for table and column names. snake_case is preferred widely.

using a function in where clause for SQL

I'm trying to use a function in the where clause to get the previous business date in order to calculate the delta of a column in the table
I'm using the following query which isn't working:
select db1.x, db2.date, db1.date, db1.y as ValNow, db2.y as ValPrevious
from db db1, db db2
where db1.x = 275305
and db1.x = db2.x
and (dbo.getLastBusinessDate(db1.date) = db2.date)
order by db1.date
I need to use the function because it will include special dates where there are no values
EDIT:
Sorry for the vague message the error that I'm getting is
Msg 557, Level 16, State 2, Line 1
Only functions and some extended stored procedures can be executed from within a function.
I just want to display the values side by side right now to confirm that the sql statement is working correctly, I planned to use the following statement to calculate delta
select db1.date, db1.x, (db1.y - db2.y) as delta , DAY(db1.date), DAY(db2.date)
from
db db1
inner JOIN db db2 on db1.x = db2.x and dbo.getLastBusinessDate(db1.date) = db2.date
order by date desc
First you use LEFT JOIN because first date doesnt have "previous date". You may want handle that null.
Then in the join you use doble condition, first db1.x = db2.x and db1.date > db2.date to make sure you match an early date.
In the where you have to make sure you select the exact previous date.
This should work in both MySql or SqlServer, but in sql server you can use window function for a better result.
SELECT
db1.x,
db2.date,
db1.date,
db1.y as ValNow,
db2.y as ValPrevious
FROM
db db1
LEFT JOIN db db2
ON db1.x = db2.x
AND db1.date > db2.date
WHERE db1.x = 275305
AND not exist (SELECT db3.date
FROM db db3
WHERE db3.date > db2.date
AND db3.date < db1.date)
ORDER BY db1.date

MySQL Query gets too complex for me

I'm trying to write a MYSQL Query that updates a cell in table1 with information gathered from 2 other tables;
The gathering of data from the other 2 tables goes without much issues (it is slow, but that's because one of the 2 tables has 4601537 records in it.. (because all the rows for one report are split in a separate record, meaning that 1 report has more than 200 records)).
The Query that I use to Join the two tables together is:
# First Table, containing Report_ID's: RE
# Table that has to be updated: REGI
# Join Table: JT
SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100
This returns 100 records (I limit it because the database is in use during work hours and I don't want to steal all resources).
However, I want to use these results in a Query that updates the REGI table (which it uses to select the 100 records in the first place).
However, I get the error that I cannot select from the table itself while updateing it (logically). So I tried selecting the select statement above into a temp table and than Update it; however, then I get the issue that I get to much results (logically! I only need 1 result and get 100) however, I'm getting stuck in my own thougts.. I ultimately need to fill the ReportID into each record of REGI.
I know it should be possible, but I'm no expert in MySQL.. is there anybody that can point me into the right direction?
Ps. fixing the table containing 400k records is not an option, it's a program from an external developer and I can only read that database.
The errors I'm talking about are as follows:
Error Code: 1093. You can't specify target table 'TrialTable' for update in FROM clause
When I use:
UPDATE TrialTable SET TrialTable.BlanccoReport =
(SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100)
WHERE TrialTable.HardwareType="PC" AND TrialTable.BlanccoReport=0)
Then I tried:
UPDATE TrialTable SET TrialTable.BlanccoReport = (SELECT ReportID FROM (<<and the rest of the SQL>>> ) as x WHERE X.SerialNo = TrialTable.Serienummer)
but that gave me the following error:
Error Code: 1242. Subquery returns more than 1 row
Haveing the Query above with a LIMIT 1, gives everything the same result
Firstly, your query seems to be functionally identical to the following:
SELECT RE.report_id ReportID
, REGI.Serienummer SerialNo
FROM Blancco_Registration.TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92
LIMIT 100
So, why not use that?
EDIT:
I still don't get it. I can't see what part of the problem the following fails to solve...
UPDATE TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
SET TrialTable.BlanccoReport = RE.report_id
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92;
(This is not an answer, but maybe a pointer towards a few points that need further attention)
Your JT sub query looks suspicious to me:
(SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92
GROUP BY RE.report_id)
You use group by but don't actually use any aggregate functions. The column RE.Value_string should strictly be something like MAX(RE.Value_string) instead.