Selecting a single row in MySQL - php

I am using MySQL, I have a table that has 9 columns. One of them is the primary key.
How can I select a single row, by the primary key or column 8 or 4?

If I understand your question correctly:
SELECT * FROM tbl WHERE id = 123 OR colname4 = 'x' OR colname8 = 'y' LIMIT 1
The 'LIMIT' keyword makes sure there is only one row returned.

select *
from MyTable
where MyPrimaryKey = 123

Columns in SQL don't have a defined 'order'. Database systems generally keep track of an order for display purposes, but it doesn't make sense to ask a database to select a column by number. You need to know the column's name in order to query its contents.
The same thing goes for the primary key (which, incidentally, may not be just a single column). You have to know which column it is, and what that column is named, in order to execute a query.
If you don't know these things, or need to figure them out dynamically, then
DESCRIBE tablename;
will tell you the names of each column, and whether it is part of the primary key or not. It will return a table that you can read, like any other result.

Related

Adding a Row into an alphabetically ordered SQL table

I have a SQL table with two columns:
'id' int Auto_Increment
instancename varchar
The current 114 rows are ordered alphabetically after instancename.
Now i want to insert a new row that fits into the order.
So say it starts with a 'B', it would be at around id 14 and therefore had to 'push down' all of the rows after id 14. How do i do this?
An SQL table is not inherently ordered! (It is just a set.) You would simply add the new row and view it using something like:
select instancename
from thetable
order by instancename;
I think you're going about this the wrong way. IDs shouldn't be changed. If you have tables that reference these IDs as foreign keys then the DBMS wouldn't let you change them, anyway.
Instead, if you need results from a specific query to be ordered alphabetically, tell SQL to order it for you:
SELECT * FROM table ORDER BY instancename
As an aside, sometimes you want something that can seemingly be a key (read- needs to be unique for each row) but does have to change from time to time (such as something like a SKU in a product table). This should not be the primary key for the same reason (there are undoubtedly other tables that may refer to these entries, each of which would also need to be updated).
Keeping this information distinct will help keep you and everyone else working on the project from going insane.
Try using an over and joining to self.
Update thetable
Set ID = r.ID
From thetable c Join
( Select instancename, Row_Number() Over(Order By instancename) As ID
From CollectionStatus) r On c.instancename= r.instancename
This should update the id column to the ordered number. You may have to disable it's identity first.

Fetching few records from mysql database having million entries

I have a table which has million rows. It has user id as its primary key. I have an array having 500 user ids in it.
I want to select all the records from the table whose user ids are in the array. I know one method to do this is to change the array into a string and run IN query by passing the string.
But I think it is not the efficient way to do it. So kindly suggest other ways.
I am assuming that your ids are integer. Maybe you are getting this list of Ids from some other sources so that a join on mysql side is not desired solution. If yes, then find the maximum and minimum id present in your 500 Ids list. You can do this in php side. When you have the max and min value, then query mysql db with a where clause
select ...
from table_name
where min_id <= id and id <= max_id
id is the primary key so the advantage is that it is already indexed.
I have done this in the past, I am not sure that my method is the most efficient.
I create a string out of the ids: where id = a or id = b or id = c ...
then I add the select statement in front of it, and do a fetchall.
My guess is that you're getting these user IDs from another table and that you are storing them in an array. If this is correct, then you should change the query that fetches these user IDs so that it uses a join instead.
Joins will help you there, because IN() is not a good programming practice.
You can learn about joins here : http://mysqljoin.com/

ROWNUM doesn't work; trying to grab info on specific row range in SQL query

I have a bit of code that counts the number of rows upon an SQL query and then does another query to grab information on the last four rows. I've used ROWNUM, but it doesn't work.
$newscount = $db->query("
SELECT *
FROM news
");
$counter = $newscount->rowCount();
$grabnewsmsg = $db->query("
SELECT *
FROM news
WHERE ROWNUM >= $counter-4 -- this particular part doesn't owrk
ORDER BY updateno DESC -- an A_I column
");
I've commented the specific areas I'm having problems. The A_I part is fine, since there should be a unique identifier for each row, but ROWNUM just doesn't work despite what I have read on other sites in addition to other questions/answers on SO. It returns an error column rownum does not exist.
I want to get information on solely the last four rows ($query->rowCount()-4), but I can't select via a certain updateno threshhold. If a user deletes a row, the A_I column cannot be appropriately used to determine the row number.
Additionally, I've tried the below:
$grabnewsmsg = $db->query("
SELECT *
FROM news
ORDER BY updateno DESC
LIMIT 0,4
");
And while this gives the desired results, I'm still not sure why ROWNUM doesn't work.
You need to understand the meaning of that AUTO_INC thingy. It is called an unique identifier, and for a reason. "Unique" means no other row should have the same identifier ever.
Yet it has absolutely nothing to do with whatever enumeration. So -
I have an autoincrementing column titled 'updateno' which corresponds to the number of the row.
this is what you are doing wrong.
As a matter of fact, you don't need such a field at all. If you wnat to enumerate your fields - do in on the fly. If you want an identifier - use a conventional name for this - "id"
While for the whatever "rownum" feature you need another mysql operator, namely LIMIT

How to count the number of rows before a given row in MySQL with CodeIgniter?

Simply put, how can I count how many rows there are before a certain row. I'm using incremental ID's, but rows are deleted a random, so just checking to see what the ID is won't work.
If I have, say, 30 rows, and I've selected one based on a name (or anything really), how many rows are there before that one? It could be 16, 1, 12, or anything.
I'm using MySQL and CodeIgniter.
I assume your primary key column has datatype integer
SELECT COUNT(*) FROM `table`
WHERE id < (SELECT id FROM `table` WHERE `conditions are met for specific row`)
Assuming it's an auto_increment column, deleted rows won't be filled in again so this should do the job.
SELECT COUNT(*) FROM table WHERE id_column < your_selected_row_id;
On your model:
$id = $this->db->get('users')->where("name", "John")->id;
$rows = $this->db->get('users')->where("id < ", $id)->num_rows();
return $rows;
Notice how I'm using "chained methods" and for that you need PHP5 which is the default for CI 2.
You first need to get the ID of the record you need to start counting "backwards" which is the first line, considering a table called users and that the column you are filtering is "name" and the row you want to find has the name value of John.
The second line will give you the number of rows that the query "where id < number" returned where number is the ID you got from the first query. Maybe you can even chain both lines.

Unique Primary Id exchange in on mysql?

i got an sql table which contains data for a menu in the php page.
SELECT * FROM `hizlierisim` ORDER BY id LIMIT 0 , 10
it is ordered by id row.but im asked to add order control on admin panel.
So there will Up&Down Buttons to re-arrange menu items.
i guess there is two ways to do this
one is to create a row called 'order' and change sql query to:
SELECT * FROM `hizlierisim` ORDER BY `order` LIMIT 0 , 10
or
exchange id's of the columns that we wanted to move.
and still use same sql:
SELECT * FROM `hizlierisim` ORDER BY id LIMIT 0 , 10
id method seems easier but i wonder if there is a possibility to exchange id's of two columns on mysql?
Messing with primary key fields just to satisfy some arbitrary ordering requirement is a bad idea. Especially in a foreign key situation. Add an 'order' column (which is a reserved word, by the way, so use something else if you want to save yourself some pain) is the practical option.
Changing PK IDs for this sort of functionality is a very bad practice; far better to introduce an ordering column and use that to sort by. Obviously don't call it ORDER as that's a reserved word...
The id of a row should be static, a permanent unique identifier for the record, such that it can be stored as a foreign key elsewhere.
Creating the "order_id" as you suggest would be preferable. This can be changed to any value you like without a side-effect, it's for ordering, changing it only effects ordering.
In terms of "swapping" values, there isn't anything I'm aware of, you just need to code it yourself.
Either...
BEGIN TRANSACTION
UPDATE x SET order_id = NULL WHERE order_id = 11
UPDATE x SET order_id = 11 WHERE order_id = 10
UPDATE x SET order_id = 10 WHERE order_id IS NULL
COMMIT TRANSACTION
(or similar)
Or maybe something like...
UPDATE
x
SET
order_id = CASE order_id WHEN 11 then 10 ELSE 11 END
WHERE
order_id IN (10,11)
By "exchange" I assume you're talking about updating primary key values of two columns which is horrible, HORRIBLE idea - I can't stress enough how bad it is and what implications it might have. I suggest you do some reading on what primary keys are and why you should never play with them.
Add another field and update it with values 0, 1 and so on and order on that column. You can also specify multiple columns in your ORDER BY clause which allows you to order by primary key and some other column(s).

Categories