Could someone help me create an SQL query that could work below MySQL 8. Currently, this query is working on my localhost but when transferred to the Live was showing an error.
This query scores the racers from 10 to 1 (1st place = 10pts, 10th place = 1point) that runs automatically on Monday Midnight.
Here's the sample table:
CREATE TABLE `tbl_race_has_list` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`group_name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`timer` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`weekly_score` SMALLINT NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
$sql = "UPDATE tbl_race_has_list
INNER JOIN
(
SELECT *, ROW_NUMBER() OVER (order by timer ASC) AS RacerRank
FROM tbl_race_has_list
WHERE DATE(created)
BETWEEN DATE_SUB(DATE(now()), INTERVAL (WEEKDAY(now()) - 1 + 7) % 7 DAY)
AND DATE_ADD(DATE(now()), INTERVAL 6 - (WEEKDAY(now()) - 1 + 7) % 7 DAY)
ORDER BY timer ASC LIMIT 0, 10
) c
ON racerTime.tbl_race_has_list.id = c.id
SET racerTime.tbl_race_has_list.weekly_score = 11 - c.RacerRank";
Update. I created an SQL query that could work below MySQL 8 ver. It is working as intended but I am open to a better approach.
UPDATE tbl_race_has_list
INNER JOIN
(
SELECT *, (#row_number := #row_number + 1) AS RacerRank
FROM tbl_race_has_list
(SELECT #row_number := 0) AS x
WHERE DATE(created)
BETWEEN DATE_SUB(DATE(now()), INTERVAL (WEEKDAY(now()) - 1 + 7) % 7 DAY)
AND DATE_ADD(DATE(now()), INTERVAL 6 - (WEEKDAY(now()) - 1 + 7) % 7 DAY)
ORDER BY timer ASC LIMIT 0, 10
) c
ON racerTime.tbl_race_has_list.id = c.id
SET racerTime.tbl_race_has_list.weekly_score = 11 - c.RacerRank
The code you showed at the start of your question should work fine in MySQL 8.0.
But we learned in the comment thread above that you are not using MySQL at all, you are using MariaDB. MariaDB is not MySQL. It forked from MySQL in 2010 and has been growing more incompatible gradually since then. We should think of MariaDB as a different product now, not a drop-in replacement for MySQL as they once claimed.
On your production server, you are using a MariaDB 10.1, which is too old to support window functions. See their documentation: https://mariadb.com/kb/en/window-functions/
Window functions were first introduced in MariaDB 10.2.0.
It's a good habit to make sure your development environment has the exact same versions of all components of your complete technology stack. Otherwise you risk exactly what happened in this case, you develop some code that relies on newer features, and then find that the code doesn't work when you deploy to production.
You should insist that your production server gets updated. MariaDB 10.1 passed its end of life in October 2020, according to https://endoflife.date/mariadb.
Failing that, try to find a version of MariaDB 10.1 to install in your development. That might take some creative searching, because 10.1 has been removed from the official download site: https://mariadb.com/downloads/
Related
This question already has answers here:
MySQL error 1064 syntax but everything seems fine
(3 answers)
Closed 3 years ago.
created this with my sql and unsure what is wrong with the script
CREATE TABLE IF NOT EXISTS `restaurant`.`restaurant` (
`_id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`added_date` VARCHAR(30) NULL,
`tele_number` VARCHAR(8) NULL,
`about` TEXT(1024) NULL,
`average_rating` INT NULL,
`price` VARCHAR(10) NULL,
`opening_hour` VARCHAR(255) NULL,
`restaurantcol` VARCHAR(45) NULL,
PRIMARY KEY (`_id`),
UNIQUE INDEX `_id_UNIQUE` (`_id` ASC) VISIBLE,
UNIQUE INDEX `tele number_UNIQUE` (`tele_number` ASC) VISIBLE)
ENGINE = InnoDB
error given:
Error Code: 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 ' UNIQUE INDEX tele number_UNIQUE (tele_number ASC) VISIBLE) ENGINE = InnoD' at line 12
The error messages of MySQL contain the part of the query that has not been parsed because the last parsed token is the one that produces the error. This means the word before " UNIQUE INDEX tele number_UNIQUE ..." is the problem. That word is VISIBLE.
The VISIBLE keyword has been introduced in MySQL 8.0 and you probably use an earlier version.
By default, the indexes are VISIBLE. You can safely drop this keyword from the query. On MySQL 8 you will get the same result as when you use it. On MySQL 5 the concept of invisible indexes does not exist, all indexes are visible.
I see now in the error message that you are not using MySQL but MariaDB. MariaDB is a fork of MySQL 5 that is compatible with MySQL up to some point. You will find many small differences here and there.
I'm trying to convert my SQlite code to Mariadb but i'm stuck with a query for a crossed table between two another tables
The purpose of the table is to add ID from the other table but only if they don't exists
I have two tables
Table COMPUTERS
ID(primary) / NETBIOS(unique) / IP / SOFTWARE_STAT / COPY_STAT / AV_STAT
ex : 1 PC1 192.168.1.1 KO KO 0
Table SOFTWARES
ID(primary) / NAME(unique)
ex : 1 ADOBE
And the cross table
Table INSTALL
ID (primary)/ COMPUTER_ID / SOFTWARE_ID / FAIL
1 1 1 0
My SQLITE code below is working
INSERT OR IGNORE INTO INSTALL (COMPUTER_ID,SOFTWARE_ID)
SELECT
(SELECT ID FROM COMPUTERS WHERE IP = '192.168.1.1'),
(SELECT ID FROM SOFTWARES WHERE NOM = 'ADOBE')
WHERE NOT EXISTS
(SELECT
COMPUTER_ID,SOFTWARE_ID FROM INSTALL
WHERE
COMPUTER_ID = (SELECT ID FROM COMPUTERS WHERE IP = '192.168.1.1')
AND
SOFTWARE_ID = (SELECT ID FROM SOFTWARES WHERE NOM = 'ADOBE')
)
I've tried that
INSERT INTO INSTALL (COMPUTER_ID,SOFTWARE_ID)
SELECT
(SELECT RowID FROM COMPUTERS WHERE IP='192.168.1.1'),
(SELECT RowID FROM SOFTWARES WHERE NOM='ADOBE')
WHERE NOT EXISTS
(SELECT COMPUTER_ID,SOFTWARE_ID FROM INSTALL
WHERE
COMPUTER_ID = (SELECT RowID FROM COMPUTERS WHERE IP='192.168.1.1')
AND
SOFTWARE_ID = (SELECT RowID FROM SOFTWARES WHERE NOM='ADOBE'));
Without success
Someone have an idea ? Thanks in advance.
INSERT OR IGNORE --> INSERT IGNORE
However, you have a redundancy: (1) IGNORE, and (2) NOT EXISTS. That is, you both verify that it is not a dup and you ignore errors if it is.
Otherwise, the Sqlite code should work as is in MariaDB. What went wrong? Did you get an error?
MariaDB has no RowID.
I'm facing a strange error. I have a 5.5.5-10.1.20-MariaDB install on my local mac (brew) and a 5.5.52-MariaDB on my prod server (centos7). My local DB content is a copy from my server DB. I've executed this query on local:
## CREATE DIRECT RELATION BETWEEN JOURNAL AND PUBLICATION
INSERT INTO journal_publication (journal_id, `publication_id`) (
select issues.journal_id as journal_id, publications.id as publication_id from issues
join publications on issues.id = publications.`issue_id`
where publications.id Not In (select distinct publication_id from journal_publication)
);
It works fine and takes only less than a second to execute.
Now when I try the exact same query on my prod server, the query is never ending and takes all CPUs. Moreover, I've tried to EXPLAIN the query, it works fine on my local:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY issues index PRIMARY issues_journal_id_foreign 5 NULL 70993 Using index; Using temporary
1 PRIMARY publications ref publications_issue_id_foreign publications_issue_id_foreign 5 pubpeer.issues.id 1 Using where; Using index
2 MATERIALIZED journal_publication index NULL PRIMARY 8 NULL 143926 Using index
Whereas the same query on my Prod returns an error:
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 'INSERT INTO journal_publication (journal_id, `publication_id`)
(select issues.j' at line 2
Again, the content of the two DBs are identical, primary keys and indexes are set equally. For the record, when I try and execute this query:
select issues.journal_id as journal_id, publications.id as publication_id from issues
join publications on issues.id = publications.`issue_id`
where publications.id Not In (select distinct publication_id from journal_publication;
either on local or prod takes only a second.
Have you got any clue or process I could follow to help me understand these differences?
Thanks.
Xavier
MariaDB server versions < 10.0 only support EXPLAIN SELECT
MariaDB server versions >= 10.0 support additionally EXPLAIN
UPDATE, EXPLAIN INSERT and EXPLAIN DELETE
Please note that the version string 5.5.5-10.1.20-MariaDB means MariaDB 10.1.20, the 5.5.5 prefix is required since MySQL replication would break, since it supports only 1 digit numbers for the major version.
See also EXPLAIN UDATE/INSERT/DELETE in MySQL and MariaDB
This question already has answers here:
Identity increment is jumping in SQL Server database
(6 answers)
Closed 7 years ago.
I have a strange scenario in which the auto identity int column in my SQL Server 2012 database is not incrementing properly.
Say I have a table which uses an int auto identity as a primary key it is sporadically skipping increments, for example:
1,
2,
3,
4,
5,
1004,
1005
This is happening on a random number of tables at very random times, can not replicate it to find any trends.
How is this happening?
Is there a way to make it stop?
This is all perfectly normal. Microsoft added sequences in SQL Server 2012, finally, i might add and changed the way identity keys are generated. Have a look here for some explanation.
If you want to have the old behaviour, you can:
use trace flag 272 - this will cause a log record to be generated for each generated identity value. The performance of identity generation may be impacted by turning on this trace flag.
use a sequence generator with the NO CACHE setting (http://msdn.microsoft.com/en-us/library/ff878091.aspx)
Got the same problem, found the following bug report in SQL Server 2012
If still relevant see conditions that cause the issue - there are some workarounds there as well (didn't try though).
Failover or Restart Results in Reseed of Identity
While trace flag 272 may work for many, it definitely won't work for hosted Sql Server Express installations. So, I created an identity table, and use this through an INSTEAD OF trigger. I'm hoping this helps someone else, and/or gives others an opportunity to improve my solution. The last line allows returning the last identity column added. Since I typically use this to add a single row, this works to return the identity of a single inserted row.
The identity table:
CREATE TABLE [dbo].[tblsysIdentities](
[intTableId] [int] NOT NULL,
[intIdentityLast] [int] NOT NULL,
[strTable] [varchar](100) NOT NULL,
[tsConcurrency] [timestamp] NULL,
CONSTRAINT [PK_tblsysIdentities] PRIMARY KEY CLUSTERED
(
[intTableId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
and the insert trigger:
-- INSERT --
IF OBJECT_ID ('dbo.trgtblsysTrackerMessagesIdentity', 'TR') IS NOT NULL
DROP TRIGGER dbo.trgtblsysTrackerMessagesIdentity;
GO
CREATE TRIGGER trgtblsysTrackerMessagesIdentity
ON dbo.tblsysTrackerMessages
INSTEAD OF INSERT AS
BEGIN
DECLARE #intTrackerMessageId INT
DECLARE #intRowCount INT
SET #intRowCount = (SELECT COUNT(*) FROM INSERTED)
SET #intTrackerMessageId = (SELECT intIdentityLast FROM tblsysIdentities WHERE intTableId=1)
UPDATE tblsysIdentities SET intIdentityLast = #intTrackerMessageId + #intRowCount WHERE intTableId=1
INSERT INTO tblsysTrackerMessages(
[intTrackerMessageId],
[intTrackerId],
[strMessage],
[intTrackerMessageTypeId],
[datCreated],
[strCreatedBy])
SELECT #intTrackerMessageId + ROW_NUMBER() OVER (ORDER BY [datCreated]) AS [intTrackerMessageId],
[intTrackerId],
[strMessage],
[intTrackerMessageTypeId],
[datCreated],
[strCreatedBy] FROM INSERTED;
SELECT TOP 1 #intTrackerMessageId + #intRowCount FROM INSERTED;
END
In my project, I have a database in SQL which was working fine. But now I have to make the application support oracle db too.
Some limitations I found out was that in Oracle, there is no bit field and the table name cannot be greater than 30 char. Is there any other limitation that I need to keep in mind.
Any suggestion from past experience will be helpful.
If I recall correctly from my earlier Oracle days:
there's no IDENTITY column specification in Oracle (you need to use sequences instead)
you cannot simply return a SELECT (columns) from a stored procedure (you need to use REF CURSOR)
of course, all stored procs/funcs are different (Oracle's PL/SQL is not the same as T-SQL)
The SQL ISNULL counterpart in Oracle is NVL
select ISNULL(col, 0)...
select NVL(col, 0)...
You will also struggle if you attempt to select without a from in Oracle. Use dual:
select 'Hello' from DUAL
Bear in mind also, that in Oracle there is the distinction between PL/SQL (Procedural SQL) and pure SQL. They are two distinct and separate languages, that are commonly combined.
Varchar in Oracle Databases called
varchar2 is limited to 4000
characters
Oracles concept of temporary tables is different, they have a global redefined structure
by default sort order and string compare is case-sensitive
When you add a column to a select *
Select * from table_1 order by id;
you must prefix the * by the table_name or an alias
Select
(row_number() over (order by id)) rn,
t.*
from table_1 t
order by id;
Oracle doesn't distinguish between null and '' (empty string). For insert and update you ca use '', but to query you must use null
create table t1 (
id NUMBER(10),
val varchar2(20)
);
Insert into t1 values (1, '');
Insert into t1 values (2, null);
Select * from t1 where stringval = 0; -- correct but empty
Select * from t1 where stringval is null; -- returns both rows
ORACLE do not support TOP clause. Instead of TOP you can use ROWNUM.
SQL Server: TOP (Transact-SQL)
SELECT TOP 3 * FROM CUSTOMERS
ORACLE: ROWNUM Pseudocolumn
SELECT * FROM CUSTOMERS WHERE ROWNUM <= 3