SELECT statement with where clause IN is not reading variable in MySQL - mysql

I'm running SELECT statement (database MySQL version 5.5.27 under Windows 7) with variable in WHERE clause. It supposed to return 6 records, but it doesn't. Below is a simple test code.
-- Test-I
SET #group_saids := (SELECT REPLACE(
'''ClicPlan - España|ClicPlan - Francia|ClicPlan - UK|ClicPlan - Belgique|ClicPlan - Argentina|Clicplan - Turkey'''
,'|',"','") as aids_list from dual);
select #group_saids from dual;
select sd.aid
FROM said_aid sd
where sd.said in (#group_saids);
-- No records selected;
-- Test-II
select sd.aid
FROM said_aid sd
where sd.said in ('ClicPlan - España','ClicPlan - Francia','ClicPlan - UK',
'ClicPlan - Belgique','ClicPlan - Argentina',
'Clicplan - Turkey');
aid
----
3045
3253
3254
3260
3268
3270
In the code above Test-I, select from table said_aid doesn't return records, but should be 6 records output.
Int the Test-II same query with hard coded IN values return 6 records output.
No ERRORS during execution.

You have to use FIND_IN_SET() , because the IN clause expects literal values, so it won't work with the values inside a string variable, so replace your following line:
where sd.said in (#group_saids);
for this one:
where FIND_IN_SET(sd.said, #group_saids);

Related

Compairing two strings in MYSQL

I have a sequence of 20 numbers from 0 to 2, I want to compare this string with other sequences saved in my database, the problem is that the lenght of the strings saved on the database fluctuates.Also the comparison needs to be done from the end to the start.
Example of what I want:
20 digits string:
'1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1'
couple of strings saved in the database:
1 - '1,1,2,1'
2 - '2,1,2,2,2,2'
3 - '2,1'
4 - '1,1,2,1,2,1'
In this case the query would return the 1 and 3 only
create table mytable ( s varchar(60) );
insert into mytable values
('1,1,2,1'),
('2,1,2,2,2,2'),
('2,1'),
('1,1,2,1,2,1');
set #x = '1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1';
select s from mytable
where right(#x, length(s)) = s;
Output:
s
1,1,2,1
2,1
Fiddle: https://www.db-fiddle.com/f/r5m2hPbnmUu5VQfYvMVtir/0
You could use a LIKE trick here. For example, to check for the first string 1,1,2,1:
SELECT *
FROM yourTable
WHERE ',1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1,' LIKE '%,1,1,2,1,%';

Converting mysql query to mssql query for sql server 2000

I was stuck figuring out why there's error when I execute the mysql query on mssql query. I was using sql server 2000. My goal is to achieve the result with the same way that I use on mysql.
A little explanation about the database: The database is about a gps tracker with 3 main table: incoming, md_login, and master_device.
Here is the table and the structure that I will give:
Structure of table incoming:
This table mainly used for the incoming data of the gps tracker for each vehicle, so every interval there'll be incoming data into this tables. Regarding about some of the table structure, you can say 'tanggal' is the meaning of 'date' in English
Text1 varchar
...
Text18 varchar <used as imei>
...
Text31 varchar
Distance varchar
Tanggal datetime
TanggalIncoming datetime
StartDate datetime
EndDate datetime
EngineStatus varchar
AccStatus varchar
Moving varchar
Address varchar
Structure of table md_login:
This table used to store the vehicle with the imei data, so 1 Log_ID can have many Log_DeviceID.
Log_ID char <used as username>
Log_DeviceID varchar <used as vehicle number>
Log_DeviceIMEI varchar <used as imei>
Log_Date datetime
Sample data of table md_login:
Log_ID - Alex
Log_DeviceID - B 7777 GHI
Log_DeviceImei - 012896001194123
Log_Date - 2017-05-30 13:46:57
Structure of table master_device:
Device_Imei varchar
Device_PoliceNumber char
Device_MobileNumber char
Device_MobileNumber2 char
Model varchar
Port char
PortDevice char
ActiveDate datetime
LastUpdate datetime
IdxConn varchar
CommandOperate char
Picture varchar
Sample data of table master_device:
Device_Imei - 012896001194123
Device_PoliceNumber - B 7777 GHI
Device_MobileNumber - 01234567
Device_MobileNumber2 -
Model - STV-08
Port - 340
PortDevice - 20557
ActiveDate - 2017-05-30 13:46:57
LastUpdate - Null
IdxConn - Null
CommandOperate - Null
Picture - livina_grey.png
Here's the query that already works on mysql:
SELECT fi.text18 as Imei,
md.Device_PoliceNumber,
fi.Text6 as Lat,
fi.Text8 as Lng,
fi.Text10 as Speed,
fi.Text16 as Gps_Signal,
fi.Text21 as Battery,
fi.Text22 as Charging,
fi.Text29 as Oil,
fi.Text30 as Temperature,
md.Picture,
fi.EngineStatus,
fi.TanggalIncoming,
fi.Moving,
fi.Address
FROM incoming fi
INNER JOIN (SELECT MAX(tanggalincoming) as maxtglincoming,text18,moving
FROM incoming
GROUP BY text18) ri
ON ri.maxtglincoming = fi.tanggalincoming AND
ri.text18=fi.text18
INNER JOIN md_login AS mdl ON (ri.text18=mdl.log_deviceimei AND
mdl.log_id='alex')
INNER JOIN master_device AS md ON md.device_imei=mdl.log_deviceimei
GROUP BY fi.text18
ORDER BY md.Device_PoliceNumber ASC
A little explanation about the query:
So I was using MAX(tanggalincoming) at first to get the row result based on the latest update from table call incoming. the next step is: I was doing the inner join from the latest incoming table with the full incoming table so the data that will return is based from the latest incoming data that already inner joined.
And here is the sample data result that will be shown when I execute the query in mysql. There can be result more than 1 row data since 1 username can have more than 1 vehicle.
Imei - 012896001194123
Device_PoliceNumber - B 7777 GHI
Lat - -6.27585
Lng - 106.66172
Speed 0
Gps_Signal F
Battery - F:4.18V
Charging - 1
Oil - Null
Temperature - Null
Picture - livina_grey.png
EngineStatus - OFF
TanggalIncoming - 2017-05-31 05:25:59
Moving - STOP
Address - Example Street
But when I try to execute the query on sql server 2000, there's the error showing like this:
Server: Msg 8120, Level 16, State 1, Line 1. Column 'md.Device_PoliceNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
So the main question is: How can I achieve the same result in the sql query?
If you use aggregate functions (like MAX, SUM etc) in Sql Server, you should include all other fields in GROUP BY clause.
In this case in your sub-query you have SELECT MAX(tanggalincoming) as maxtglincoming,text18,moving but only text18 is included into GROUP BY.
Should look like this:
SELECT MAX(tanggalincoming) as maxtglincoming,text18,moving
FROM incoming
GROUP BY text18,moving
The second is you don't have any aggregate functions in the big query. So you should remove it.
If you used GROUP BY to suppress duplications, use DISTINCT instead

Mysql subquery not working properly with comma-separated value in column

I have a MySQL table Mapdetail that has resultTypeIds column storing a comma separated list of ids:
MapDetails
=============================
mapheaderid | resultTypeIds
=============================
54 | 1,4,-9999
Now, when I try it as a subquery, it does not return me the correct result while if I hard-code (1,4,-9999) it works fine
WRONG - RETURNING 1 ROW ONLY
select * from resulttypes rt where rt.resulttypeid in
(select md1.resulttypeids from mapdetail md1
where md1.mapheaderid = 54)
CORRECT - RETURNING 2 ROWS
select * from resulttypes rt where rt.resulttypeid in (1,4,-9999)
If you can't re-structure your DB (as mentioned in Comments). Try using FIND_IN_SET instead of IN
Try something like:
select * from resulttypes rt where FIND_IN_SET (rt.resulttypeid,
(select md1.resulttypeids from mapdetail md1
where md1.mapheaderid = 54))

MariaDB SELECT query not returning correct results

I have an issue returning results from a table on the MariaDB slave to my MySQL DB, when I run the following query:
SELECT * FROM t WHERE colZ = 'GM' AND hour(colTime) = 18 AND colDate = 20170306;
I get a result showing 10 rows that match the criteria,
See here
yet when I run:
SELECT * FROM t WHERE colZ IN ('GM','NS') AND hour(colTime) = 18 AND colDate = 20170306;
I get a result with 17 rows containing GM in colZ and then whatever matching Y values are expected (if any).
Like this
So the question is: why are those 7 records not returning in the initial query? I have tried changing the first query to colZ IN ('GM') and the second query to colZ = 'GM' or colZ = 'NS' and both still return the same results.
There is no perceivable difference in the 7 additional rows that show up in the second query compared to those in the first.
Even weirder, when I run the same queries on the master mySQL DB, both return the 17 rows as expected.

Using the "With Clause" SQL Server 2008

Can someone show me a sample SQL server script that I can look at that uses the "With Clause"?
I am trying to use this clause to iterate through 200 databases that contain the same table that I am trying to run a query on. I am trying to avoid using a cursor because the query time takes too long as well as using a while a loop.
Can someone advise me as to what I can do.
Thank you.
Just a poke, but here's another way to write FizzBuzz :)
100 rows is enough to show the WITH statement, I reckon.
;WITH t100 AS (
SELECT n=number
FROM master..spt_values
WHERE type='P' and number between 1 and 100
)
SELECT
ISNULL(NULLIF(
CASE WHEN n % 3 = 0 THEN 'Fizz' Else '' END +
CASE WHEN n % 5 = 0 THEN 'Buzz' Else '' END, ''), RIGHT(n,3))
FROM t100
But the real power behind WITH (known as Common Table Expression http://msdn.microsoft.com/en-us/library/ms190766.aspx "CTE") in SQL Server 2005 and above is the Recursion, as below where the table is built up through iterations adding to the virtual-table each time.
;WITH t100 AS (
SELECT n=1
union all
SELECT n+1
FROM t100
WHERE n < 100
)
SELECT
ISNULL(NULLIF(
CASE WHEN n % 3 = 0 THEN 'Fizz' Else '' END +
CASE WHEN n % 5 = 0 THEN 'Buzz' Else '' END, ''), RIGHT(n,3))
FROM t100
To run a similar query in all database, you can use the undocumented sp_msforeachdb. It has been mentioned in another answer, but it is sp_msforeachdb, not sp_foreachdb.
Be careful when using it though, as some things are not what you expect. Consider this example
exec sp_msforeachdb 'select count(*) from sys.objects'
Instead of the counts of objects within each DB, you will get the SAME count reported, begin that of the current DB.
To get around this, always "use" the database first. Note the square brackets to qualify multi-word database names.
exec sp_msforeachdb 'use [?]; select count(*) from sys.objects'
For your specific query about populating a tally table, you can use something like the below. Not sure about the DATE column, so this tally table has only the DBNAME and IMG_COUNT columns, but hope it helps you.
create table #tbl (dbname sysname, img_count int);
exec sp_msforeachdb '
use [?];
if object_id(''tbldoc'') is not null
insert #tbl
select ''?'', count(*) from tbldoc'
select * from #tbl
There are two types of WITH clauses:
Here is the FizzBuzz in SQL form, using a WITH common table expression (CTE).
;WITH mil AS (
SELECT TOP 1000000 ROW_NUMBER() OVER ( ORDER BY c.column_id ) [n]
FROM master.sys.all_columns as c
CROSS JOIN master.sys.all_columns as c2
)
SELECT CASE WHEN n % 3 = 0 THEN
CASE WHEN n % 5 = 0 THEN 'FizzBuzz' ELSE 'Fizz' END
WHEN n % 5 = 0 THEN 'Buzz'
ELSE CAST(n AS char(6))
END + CHAR(13)
FROM mil
Here is a select statement also using a WITH clause
SELECT * FROM orders WITH (NOLOCK) where order_id = 123
Try the sp_foreachdb procedure.