Cannot create a mysql view from other views - mysql

I have the following views
M_VWPROC_sub1,M_VWPROC_sub2,M_VWPROC_sub3,M_VWPROC_sub4,M_VWPROC_sub5,
M_VWPROC_sub6,M_VWPROC_sub7,M_VWPROC_sub8,M_VWPROC_sub9
I tried to create a view using the following sql.but I get the following error
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
near 'M_VWPROC_sub2 union all M_VWPROC_sub3 union all M_VWPROC_sub4
union all M_VWPROC' at line 2
Query:
CREATE OR REPLACE VIEW M_VWPROC (UNIT, PS_DATE, LOCALIN, STOCKIN, STOCKOUT) AS
select inner_sub_table.UNIT,
inner_sub_table.PS_DATE,
sum(inner_sub_table.LOCALIN)LOCALIN,
sum(inner_sub_table.pur) STOCKIN,
sum(inner_sub_table.sale) STOCKOUT
from M_VWPROC_sub1
union all M_VWPROC_sub2
union all M_VWPROC_sub3
union all M_VWPROC_sub4
union all M_VWPROC_sub5
union all M_VWPROC_sub6
union all M_VWPROC_sub7
union all M_VWPROC_sub8
union all M_VWPROC_sub9)
inner_sub_table
group by inner_sub_table.UNIT, inner_sub_table.PS_DATE;
Any help. Thanks in advance.

The correct syntax for union all requires a subquery . . . that is a select clause. But, you cannot do what you want. You need another layer of subqueries. Something like:
create view v_YetAnotherView as
select * from M_VWPROC_sub1
union all select * from M_VWPROC_sub2
union all select * from M_VWPROC_sub3
union all select * from M_VWPROC_sub4
union all select * from M_VWPROC_sub5
union all select * from M_VWPROC_sub6
union all select * from M_VWPROC_sub7
union all select * from M_VWPROC_sub8
union all select * from M_VWPROC_sub9;
And then:
CREATE OR REPLACE VIEW M_VWPROC (UNIT, PS_DATE, LOCALIN, STOCKIN, STOCKOUT) AS
select inner_sub_table.UNIT,
inner_sub_table.PS_DATE,
sum(yav.LOCALIN)LOCALIN,
sum(yav.pur) STOCKIN,
sum(yav.sale) STOCKOUT
from YetAnotherView yav
group by yav.UNIT, yav.PS_DATE;
Do note that this ridiculous limitation on views (that the from clause cannot contain subqueries) is limited to MySQL.

Related

Pre populate Sql data using recursion on each combination

I am trying to fill db pre populated data from sql script where I have two type of constants or enums.
Platform: DG, NK
Department : KK, TG, LO, NP, UI, BG, ED, CC.
Task: To generate a sequential number using procedural loop and for each combination using above value we need to generate key and put in data base with count or sequence value.
Database columns:
id(auto generated), count, category_key, status
Now single row would be one combination which is formed using this pattern,
Department_Platform_SequenceNumber :: example => KK_DG_1,....KK_DG_10000, KK_NK_1,....KK_NK_10000
This is for 10k entries for 10k sequence of each combinations. It follows for other as well.
Approach:
WITH RECURSIVE
number AS ( SELECT 1 number
UNION ALL
SELECT number + 1 FROM cte WHERE number < 10000 ),
platform AS ( SELECT 'DG' platform
UNION ALL
SELECT 'NK' ),
department AS ( SELECT 'KK' department
UNION ALL
SELECT 'TG'
UNION ALL
SELECT 'LO'
UNION ALL
SELECT 'NP'
UNION ALL
SELECT 'UI'
UNION ALL
SELECT 'BG'
UNION ALL
SELECT 'ED'
UNION ALL
SELECT 'CC' )
INSERT INTO counter_key
SELECT null, number, CONCAT_WS('_', department, platform, number), 1
FROM department
CROSS JOIN platform
CROSS JOIN number;
Problem: Getting syntactical error::
Error Code: 1064. You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'INSERT INTO counter_key SELECT null, number,
CONCAT_WS('_', department, platfor' at line 23
Please help me resolve this since I have been struggling to resolve this.
There are 2 problems in query
cte does not exist in first Recursive Block.
Place the Insert INTO statement before recursive block
So your final query should be like below
insert into counter_key
WITH RECURSIVE
cte AS ( SELECT 1 number
UNION ALL
SELECT number + 1 FROM cte WHERE number < 2 ),
platform AS ( SELECT 'DG' platform
UNION ALL
SELECT 'NK' ),
department AS ( SELECT 'KK' department
UNION ALL
SELECT 'TG'
UNION ALL
SELECT 'LO'
UNION ALL
SELECT 'NP'
UNION ALL
SELECT 'UI'
UNION ALL
SELECT 'BG'
UNION ALL
SELECT 'ED'
UNION ALL
SELECT 'CC' )
SELECT null, number, CONCAT_WS('_', platform, department), 1
FROM department
CROSS JOIN platform
CROSS JOIN cte
order by 3,2;
DEMO

Php mysql bad query when displays on a table

there's my code that select 5 databases and display in a table, but the where statement not work
The where is ignored by the query.
SELECT *
FROM events
UNION ALL
SELECT * FROM eventstwo
UNION ALL
SELECT * FROM eventsthree
UNION ALL
SELECT * FROM eventsfour
UNION ALL
SELECT * FROM eventsfive where atender='$obj'
I suspect that you want the WHERE criteria to apply to every subquery in the union. If you want that, you'll have to add a WHERE clause to each subquery. But, if you really do want to use a single WHERE clause, you can wrap your union query and then subquery it:
SELECT *
FROM
(
SELECT * FROM events
UNION ALL
SELECT * FROM eventstwo
UNION ALL
SELECT * FROM eventsthree
UNION ALL
SELECT * FROM eventsfour
UNION ALL
SELECT * FROM eventsfive
) t
WHERE atender = '$obj';
Side note: Please use prepared statements in your PHP code wherever possible.
SELECT * FROM
( SELECT *
FROM events
UNION ALL
SELECT * FROM eventstwo
UNION ALL
SELECT * FROM eventsthree
UNION ALL
SELECT * FROM eventsfour
UNION ALL
SELECT * FROM eventsfive)
AS derived
WHERE atender='$obj'

How can I create a view with duplicate columns and merge them?

I have pm_message tables with 1~9, and I want to create a view to simplified the process of MySQL query.
What I have is
CREATE VIEW `pm_messages` AS
SELECT * FROM
`pm_messages_0`,
`pm_messages_1`,
`pm_messages_2`,
`pm_messages_3`,
`pm_messages_4`,
`pm_messages_5`,
`pm_messages_6`,
`pm_messages_7`,
`pm_messages_8`,
`pm_messages_9`;
I got error with douplicate column. There is no record is duplicate, I want to merge all of them in view, what should I do?
You have coded a colossal cross join. Depending on the number of rows, it probably wouldn't return before the universe suffers entropy heat death.
I'm almost certain you want a union:
CREATE VIEW `pm_messages` AS
SELECT * FROM `pm_messages_0` union all
SELECT * FROM `pm_messages_1` union all
SELECT * FROM `pm_messages_2` union all
SELECT * FROM `pm_messages_3` union all
SELECT * FROM `pm_messages_4` union all
SELECT * FROM `pm_messages_5` union all
SELECT * FROM `pm_messages_6` union all
SELECT * FROM `pm_messages_7` union all
SELECT * FROM `pm_messages_8` union all
SELECT * FROM `pm_messages_9`;
This will work if all tables have the same number and type of columns. If not, you'll have to explicitly select columns such that each select returns the same number and type of columns.

MySQL select from custom set and compare with table data

Hi I'm trying to solve which elements doesn't exists in my database. In order to do so I want to compare list of integers (output from external script) with data in table. How to do such thing like:
SELECT * FROM (1,1,2,3,5,8,13...) l WHERE l NOT IN (select id from table1);
This is probably best done with a left outer join. But, your problem is creating the table of constants:
SELECT *
FROM (select 1 as id union all select 2 union all select 3 union all select 5 union all
select 8 union all select 13 union all select 21 . . .
) ids
where ids.id NOT IN (select id from table1);
This can have odd behavior, if table1.id is ever NULL. The following works more generally:
SELECT *
FROM (select 1 as id union all select 2 union all select 3 union all select 5 union all
select 8 union all select 13 union all select 21 . . .
) ids left outer join
table1 t1
on ids.id = t1.id
where t1.id is null;
EDIT:
The size of a MySQL query is dictated by the parameter max_packet_size (see here). The most recent version has a limit of 1 Gbyte. You should be able to fit 18,000 rows of:
select <n> union all
into that limit, quite easily. Gosh, I don't even think it would be 1 megabyte. I would say, though, that passing a list of 18,000 ids through the application seems inefficient. It would be nice if one database could just pull the data from the other database, without going through the application.
If your set to compare is huge I'd recommend you to create a temporary table myids with the only column id, put there all your 18K values and run query like that:
select id from myids where myids.id not in (select id from table1);

What is the best way to return enum values in MySQL?

I need to select the enum values of a column. From searching I've found two ways:
SELECT column_type FROM information_schema.columns
WHERE table_name = 'MyTable' AND column_name = 'MyColumn';
and the other:
SHOW COLUMNS FROM `mytable` WHERE field = 'type';
Although the first query will give me this info:
enum('value1','value2','value3')
The second query gives me the same and with additional columns as well. I would prefer to just get those values without the enum() and commas, is it possible, or do I need to parse the values out? Not that it's hard just checking if there is an easier way.
Assuming there is no easier way, which of the two queries above is better to use? I noticed that the second query doesn't show the query time when I ran it, I almost thought it didn't require any time at all. But if I turn on the profiler I can see that it does take time, but it seem a bit faster. So would the second query be more efficient?
I guess you can't select those values out, I ended up parsing the values out with this:
$result = str_replace(array("enum('", "')", "''"), array('', '', "'"), $result);
$arr = explode("','", $result);
return $arr;
Try following if works
SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(COLUMN_TYPE, 7,
LENGTH(COLUMN_TYPE) - 8), "','", 1 + units.i + tens.i * 10) , "','", -1)
FROM INFORMATION_SCHEMA.COLUMNS
CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9) units
CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9) tens
WHERE TABLE_NAME = 'mytable'
AND COLUMN_NAME = 'mycolumn'