Order of rows changes when creating table - sql

I've a weird issue.
DROP table IF EXISTS ipl;
CREATE TABLE ipl(
match_id VARCHAR(50),
batting VARCHAR(50),
bowling VARCHAR(50),
overn VARCHAR(50),
batsman VARCHAR(50),
bowler VARCHAR(50),
super_over VARCHAR(50),
bat_runs VARCHAR(50),
extra_runs VARCHAR(50),
total_runs VARCHAR(50),
player_out VARCHAR(50),
how VARCHAR(50),
fielder VARCHAR(50));
BULK INSERT ipl
FROM 'F:\Study\Semesters\4th
Sem\COL362\HomeWork\1\Dataset\deliveries.csv'
WITH(FIELDTERMINATOR= ',');
SELECT * FROM ipl;
This is the code I'm using to make the table in SSMS. match_id goes from 1 to about 290, in increasing order in the csv file. When I executed this query once, everything was ok. But, when I did that again, some rows from the middle were moved to the last.
You can see that below:
(Note that jump from 4 to 49)
I don't know what's wrong. Please help me resolve this issue. Thanks!

SQL tables represent unordered sets. If you want rows in a particular order, you need an order by. How can you do this with a bulk insert? Well, you need an identity column. The idea is to create the table with an identity and use a view for the bulk insert:
create table ipl (
ipl_id int identity(1, 1) primary key,
. . .
);
create view vw_ipl as
select match_id, batting, bowling, . . .
from ipl
bulk insert vw_ipl
from 'F:\Study\Semesters\4th Sem\COL362\HomeWork\1\Dataset\deliveries.csv'
with (fieldterminator= ',' );
select *
from ipl
order by ipl_id;

As a relational database SQL server do not guarantee a particular order of returned data. If you need ordered data, specify order by clause.

Related

Adding Columns to Multiple Tables in SQL

I just created a database and then added a couple of hundred tables with a script like this:
CREATE TABLE CapBond
(
[timestamp] varchar(50),
[Reward] varchar(50),
[Award] varchar(50),
[Fact] varchar(50)
)
CREATE TABLE Values
(
[timestamp] varchar(50),
[Name] varchar(50),
[Test] varchar(50),
[Read] varchar(50),
[Parameters] varchar(50)
)
I realize I forgot to add two columns to each table. One for the PK and one for an FK that points back to a 'master' table.
Is there an easy way to insert columns without having to drop the DB and recreate it? Preferably with the columns inserted as the first two columns in the table?
Yes. In mysql you have the alter table command for this purpose. Check out this page for more detailed explanation
https://www.sqlservertutorial.net/sql-server-basics/sql-server-alter-table-add-column/ .
And here is the solution for the ordering of the columns
https://www.mysqltutorial.org/mysql-add-column/

Invalid table name error when creating a table

Very new to SQL, but I thought that I had at least mastered how to make tables. I am trying to create the following table and get the error 'ORA-00903: invalid table name'. I'm not sure what is wrong.
Create table order (
order_id int,
item_type varchar(50),
item_name varchar(50),
item_price decimal(10,2),
primary key(order_id)
);
I am testing this on Oralce Live SQL and it is ok as well as on my Oracle 12c Database EE, all you need to add are "". But even so, I would not recommend it to use reserved words for naming tables.
Create table "order" (
order_id int,
item_type varchar(50),
item_name varchar(50),
item_price decimal(10,2),
primary key(order_id)
);
insert into "order" values (1, 'Item', 'Name', '20.2');
select * from "order";

Creating an index in my table does not lower my cost

I have this table:
accident_info
(
accident_index varchar(20),
first_road_class varchar(20),
accident_severity varchar(20),
date date,
urban_or_rural_area varchar(20),
weather_conditions varchar(40),
year int,
inscotland varchar(20)
);
And against this table, I execute the following query :
select count(accident_index)as hits, first_road_class
from accident_info
group by first_road_class;
without index.
I would like to create an index to lower my Aggregate Cost but the one I've made so far doesn't seem to work. This is:
create index on accident_info(accident_index, first_road_class);
First ten Rows of my table
For this query:
select count(accident_index) as hits, first_road_class
from accident_info
group by first_road_class;
You can try an index on accident_info(first_road_class, accident_index). The order of the columns is important.

Insert data from one table to another table while the target table has a primary key

In SQL Server I have a table as RawTable (temp) which gets fed by a CVS, let's say it has 22 columns in it. Then, I need to copy existing records (ONLY FEW COLUMNs NOT ALL) into another table as Visitors which is not temporary table.
Visitor table has an ID column as INT and that is primary key and incremental.
RawData table
id PK, int not null
VisitorDate Varchar(10)
VisitorTime Varchar(11)
Visitors table
VisitorID, PK, big int, not null
VisitorDate, Varchar(10), null
VisitorTime Varchar(11), null
So I did:
insert into [dbo].[Visitors] ( [VisitorDate], [VisitorTime])
select [VisitorDate], [VisitorTime]
from RawTable /*this is temp table */
Seems SQL Server doesn't like this method so it throws
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'VisitorID', table 'TS.dbo.Visitors'; column does not allow nulls. INSERT fails. The statement has been terminated.
How can I keep Sql Server not to complain about the primary key? this column as you know better will be fed by sql server itself.
Any idea?
Just because your visitors table has an ID column that is the primary key doesn't mean that the server will supply your ID values for you. if you want SQL to provide the ID's then you need to alter the table definition and make the visitorsId column an IDENTITY column.
Otherwise, you can psuedo-create these id's during the insert with the ROW_NUMBER function -
DECLARE #maxId INT;
SELECT #maxId = (SELECT MAX(visitorsId) FROM dbo.visitors);
INSERT INTO [dbo].[Visitors] ( [visitorsId],[VisitorDate], [VisitorTime])
SELECT #maxId + ROW_NUMBER() OVER (ORDER BY visitorDate), [VisitorDate], [VisitorTime]
from RawTable /*this is temp table */

How to delete Duplicates in MySQL table

I've given a client the following query to delete duplicate phone no. records in an MSSQL database, but now they need to also do it on MySQL, and they report that MySQL complains about the format of the query. I've included the setup of a test table with duplicates for my code sample, but the actual delete query is what counts.
I'm asking this in ignorance and urgency, as I am still busy downloading and installing MySQL, and just maybe somebody can help in the mean time.
create table bkPhone
(
phoneNo nvarchar(20),
firstName nvarchar(20),
lastName nvarchar(20)
)
GO
insert bkPhone values('0783313780','Brady','Kelly')
insert bkPhone values('0845319792','Mark','Smith')
insert bkPhone values('0834976958','Bill','Jones')
insert bkPhone values('0845319792','Mark','Smith')
insert bkPhone values('0828329792','Mickey','Mouse')
insert bkPhone values('0834976958','Bill','Jones')
alter table bkPhone add phoneId int identity
delete from bkPhone
where phoneId not in
(
select min(phoneId)
from bkPhone
group by phoneNo,firstName,lastName
having count(*) >= 1
)
Many ways lead to Rome. This is one. It is very fast. So you can use it with big databases. Don't forget the indeces.
The trick is: make phoneNo unique and use "ignore".
drop table if exists bkPhone_template;
create table bkPhone_template (
phoneNo varchar(20),
firstName varchar(20),
lastName varchar(20)
);
insert into bkPhone_template values('0783313780','Brady','Kelly');
insert into bkPhone_template values('0845319792','Mark','Smith');
insert into bkPhone_template values('0834976958','Bill','Jones');
insert into bkPhone_template values('0845319792','Mark','Smith');
insert into bkPhone_template values('0828329792','Mickey','Mouse');
insert into bkPhone_template values('0834976958','Bill','Jones');
drop table if exists bkPhone;
create table bkPhone like bkPhone_template;
alter table bkPhone add unique (phoneNo);
insert ignore into bkPhone (phoneNo,firstName,lastName) select phoneNo,firstName,lastName from bkPhone_template;
drop table bkPhone_template;
If the data table already exists, then you only have to run a create table select with a following insert ignore select. At the end you have to run some table renaming statements. That's all.
This workaround is much,much faster then a delete operation.
You can select out the unique ones by:
select distinct(phoneNo) from bkPhone
and put them into another table, delete the old table and rename the new one to the old name.
MySQL complains, because it makes no sense. You trying to aggregate using min() column by which you group.
Now, if you're trying to delete duplicate phone numbers for the same person, the SQL should be:
delete from bkPhone
where phoneId not in
(
select min(phoneId)
from bkPhone
group by firstName,lastName /* i.e. grouping by person and NOT grouping by phoneId */
having count(*) >= 1
)
Mysql also included:
http://mssql-to-postgresql.blogspot.com/2007/12/deleting-duplicates-in-postgresql-ms.html