Why is no data being returned - sql

I am trying to find majors that end with S, but no data is being returned
create table Student
(sid char(10) primary key,
sname varchar(20) not null,
gpa float,
major char(10),
dob DATE);
insert into Student values('111', 'Joe', 3.5 , 'MIS', '01-AUG-2000');
insert into Student values('222', 'Jack', 3.4 , 'MIS', '12-JAN-1999');
insert into Student values('333', 'Jill', 3.2 , 'CS', '15-MAY-1998');
insert into Student values('444', 'Mary', 3.7 , 'CS', '17-DEC-2001');
insert into Student values('555', 'Peter', 3.8 , 'CS', '19-MAR-1999');
insert into Student values('666', 'Pat', 3.9, 'Math', '31-MAY-2000');
insert into Student values('777', 'Tracy', 4.0, 'Math', '18-JUL-1997');
SELECT * FROM STUDENT
WHERE MAJOR LIKE '%S'
This doesn't work on livesql (oracle (PL-SQL) based but works on T-SQL).
This is the error message: 'No data found'

Your CHAR(10) will always contain 10 characters so it is going to be padded with space characters. Change to VARCHAR2(10) and it will work. I'm assuming Oracle since you didn't specify which database. But VARCHAR(10) should work with T-SQL.

If you can't (or won't) modify datatype to varchar2 (not varchar as Stilgar suggested), then trimming the column might help:
SQL> select * from student
2 where trim(major) like '%S';
SID SNAME GPA MAJOR DOB
---------- -------------------- ---------- ---------- --------
111 Joe 3,5 MIS 01.08.00
222 Jack 3,4 MIS 12.01.99
333 Jill 3,2 CS 15.05.98
444 Mary 3,7 CS 17.12.01
555 Peter 3,8 CS 19.03.99

Related

Problem inserting into table in oracle using PopSQL

The problem i'm having is that using PopSQL, when i insert something into a table it says success but then it inserts nothing into the table by saying 0 rows affected and i can't figure out what is the problem because PopSQL works fine with postgres and Mysql. Any help is much appreciated.
CREATE TABLE employees
(
employee_id NUMBER PRIMARY KEY,
first_name VARCHAR2(30) NOT NULL,
last_name VARCHAR2(30) NOT NULL,
hire_date DATE NOT NULL,
salary NUMBER(8,2) NOT NULL
);
INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
COMMIT;
SELECT * FROM employees;
Seem a Sys error to me
Try this :
INSERT INTO employees (employee_id, first_name, last_name, hire_date, salary)
VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
COMMIT;
SELECT * FROM employees;
Make sure to change the VALUES clause to match the correct number of columns and data types in the employees table.
As Jonas commented, "date" value (string, actually; you just enclosed some digits and letters into single quotes) looks suspicious. Read his comment once again.
I'm in Croatia. Let's see what happens in my database.
SQL> CREATE TABLE employees
2 (
3 employee_id NUMBER PRIMARY KEY,
4 first_name VARCHAR2(30) NOT NULL,
5 last_name VARCHAR2(30) NOT NULL,
6 hire_date DATE NOT NULL,
7 salary NUMBER(8,2) NOT NULL
8 );
Table created.
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000)
*
ERROR at line 1:
ORA-01858: a non-numeric character was found where a numeric was expected
Error; can't say I didn't expect it. What does default NLS value (in my database) say about dates?
SQL> select sysdate right_now,
2 to_char(sysdate, 'dd-mon-yyyy') another_Format
3 from dual;
RIGHT_NOW ANOTHER_FORMAT
---------- --------------------
04.02.2023 04-vel-2023
SQL>
Right; format doesn't match, nor does the language. How to fix it?
One option is to use date literal instead of a string:
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', date '2010-01-01', 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ---------- ----------
100 Malik Makkes 01.01.2010 9000
SQL>
That works. Another option is to use to_date function with appropriate format model:
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes',
2 to_date('01-jan-2010', 'dd-mon-yyyy', 'nls_date_language = english'), 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ---------- ----------
100 Malik Makkes 01.01.2010 9000
SQL>
That works too. Yet another option is to alter your session (or, if you must, NLS settings for the whole database, but for that you'll need to talk to your DBA):
SQL> alter session set nls_date_format = 'dd-mon-yyyy';
Session altered.
SQL> alter session set nls_date_language = 'english';
Session altered.
SQL> INSERT INTO EMPLOYEES VALUES (100, 'Malik', 'Makkes', '01-JAN-2010', 9000);
1 row created.
SQL> select * from employees;
EMPLOYEE_ID FIRST_NAME LAST_NAME HIRE_DATE SALARY
----------- --------------- --------------- ----------- ----------
100 Malik Makkes 01-jan-2010 9000
SQL>
Works again.
Now you've seen a few valid ways to insert date value into a date datatype column. Pick one you find the most appropriate. My choice would be a date literal.
On the other hand, if that's not the issue, provide more info (illustrate execution of your code; post exact error you got).

How can I find a string separated by a space in SQL

I am trying to find a way where I can skim out records of customers where 'First Name' and 'Middle Name' has been entered in the first_name column in the customer detail table. For examples
first_name, Last_name, mobile_no
Mary Jane Smith 0400000000
Shane Angus John 0400000000
Rudy Gill 0401111111
Rachel Rose
from the above examples I only want to find records
Mary Jane Smith 0400000000
Shane Angus John 0400000000
You can use like:
select t.*
from t
where first_name like '% %';
Note: This just checks for a space. It does not guarantee that one of the names is a middle name.
here's another solution for you if you want to get more complex and account for the middle name.
create table test (first_name nvarchar(50), middle_name nvarchar(50), last_name nvarchar(75), mobile_no nvarchar(10))
insert test
select 'mary jane', null, 'smith', '0400000000'
union all
select 'shane angus', null, 'john', '0400000000'
union all
select 'rudy', 'jacob', 'gill', '0401111111'
union all
select 'rachel', 'liza', 'rose', '0400000000'
select *
from test
where middle_name is null and charindex(char(32),first_name) > 0
this won't help you though if the first name is double-worded like Bobby Jo hence the middle name check.

Check address voor 2 properties and display in same row

From the Persons table I would like to get the following output:
Number FirstName AddressAvenue AddressFloor
----------------------------------------------
1 David Long Avenue 5th Floor
2 Bob Short Avenue NULL
3 Peter Middle Avenue 1st Floor
(Apparently, Bob his address does not contain a Floor number).
I thought I would get this by running the following query:
select
p.Number
p.FirstName
, case when (p.Street like '%Avenue%') then p.Street end as AddressAvenue
, case when (p.Street like '%Floor%') then p.Street end as AddressFloor
from
#persons
;
However, the output is as follows:
Number FirstName AddressAvenue AddressFloor
----------------------------------------------
1 David Long Avenue NULL
2 Bob Short Avenue NULL
3 Peter Middle Avenue NULL
1 David NULL 5th Floor
3 Peter NULL 1st Floor
Question How can I get both Address and Floor on the same line?
Any help is greatly appreciated!
Try this bad boy
CREATE TABLE #persons
(
Number INT
,FirstName VARCHAR(10)
,Street VARCHAR(50)
)
INSERT #persons
VALUES
(1, 'David', 'Long Avenue'),
(2, 'Bob', 'Short Avenue'),
(3, 'Peter', 'Middle Avenue'),
(1, 'David', '5th Floor'),
(3, 'Peter', '1st Floor')
--This is the code you really want, I just needed the rest to test it and make sure it worked
SELECT DISTINCT
z.Number
,z.FirstName
,(SELECT p.Street FROM #persons p where p.Street LIKE '%Avenue%' AND p.Number = z.Number)
,(SELECT p.Street FROM #persons p where p.Street LIKE '%Floor%' AND p.Number = z.Number)
FROM #persons z
DROP TABLE #persons
Results in the following:

SELECT From Multiple tables with many to many relations

Hello everyone I have inherirted a poorly designed database and I need to get some information from 3 tables
Franchise
Id(Int, PK)
FrID (varchar(50))
FirstName (varchar(50))
LastName (varchar(50))
Store
Id (Int, PK)
FrID (varchar(50))
StoreNumber (varchar(50))
StoreName
Address
Pricing
Id (int, PK)
StoreNumber (varchar(50))
Price1
Price2
Price3
and the data
ID, FrID ,FirstName,LastName
1, 10 ,John Q , TestCase
2, 10 ,Jack Q , TestCase
3, 11 ,Jack Q , TestCase
ID, FrID, StoreNumber , StoreName , Address
10, 10 , 22222 , TestStore1, 123 Main street
11, 10 , 33333 , TestStore2, 144 Last Street
12, 10 , 44444 , TestStore2, 145 Next Street
13, 11 , 55555 , Other Test, 156 Other st
ID, StoreNumber, Price1, Price2, Price3
1, 22222 , 19.99, 20.99 , 30.99
2, 33333 , 19.99, 20.99 , 30.99
3, 44444 , 19.99, 20.99 , 30.99
4, 55555 , 19.99, 20.99 , 30.99
Here is what I have done
SELECT F.FirstName,F.LastName,F.FrID , S.StoreNumber,S.StoreName,S.Address,
P.Price1,P.Price2,P.Price3
FROM Franchisee F
JOIN Store S on F.FrID = S.FrID
JOIN Pricing P on P.StoreNumber = S.StoreNumber
This part works, but I end up with lots of duplicates, For example Jack Q gets listed for his store plus every store that John Q is on. Is there anyway to fix this with out a database redesign.
Okay, there is a whole laundry list of issues such as character fields such as [FrId] being used as strings, reserved words such as [address] being used as name, etc.
Let's put the bad design issues aside.
First, I need to create a quick test environment. I did not put in Foreign Keys since that constraint is not needed to get the correct answer.
--
-- Setup test tables
--
-- Just playing
use Tempdb;
go
-- drop table
if object_id('franchise')> 0
drop table franchise;
go
-- create table
create table franchise
(
Id int primary key,
FrID varchar(50),
FirstName varchar(50),
LastName varchar(50)
);
-- insert data
insert into franchise values
( 1, 10, 'John Q', 'TestCase'),
( 2, 10, 'Jack Q', 'TestCase'),
( 3, 11, 'Jack Q', 'TestCase');
-- select data
select * from franchise;
go
-- drop table
if object_id('store')> 0
drop table store;
go
-- create table
create table store
(
Id int primary key,
FrID varchar(50),
StoreNumber varchar(50),
StoreName varchar(50),
Address varchar(50)
);
-- insert data
insert into store values
(10, 10, 22222, 'TestStore1', '123 Main street'),
(11, 10, 33333, 'TestStore2', '144 Last Street'),
(12, 10, 44444, 'TestStore2', '145 Next Street'),
(13, 11, 55555, 'Other Test', '156 Other Street');
-- select data
select * from store;
go
-- drop table
if object_id('pricing')> 0
drop table pricing;
go
-- create table
create table pricing
(
Id int primary key,
StoreNumber varchar(50),
Price1 money,
Price2 money,
Price3 money
);
-- insert data
insert into pricing values
(1, 22222, 19.99, 20.99 , 30.99),
(2, 33333, 19.99, 20.99 , 30.99),
(3, 44444, 19.99, 20.99 , 30.99),
(4, 55555, 19.95, 20.95 , 30.95);
-- select data
select * from pricing;
go
The main issue is that the franchise table should have the primary key (PK) on FrId, not Id. I do not understand why there are duplicates.
However, the query below removes them by grouping. I changed the pricing data for Jack Q to show it is a different record.
--
-- Fixed Query - Version 1
--
select
f.FirstName,
f.LastName,
f.FrID,
s.StoreNumber,
s.StoreName,
s.Address,
p.Price1,
p.Price2,
p.Price3
from
-- Remove duplicates from francise
(
select
LastName,
FirstName,
Max(FrID) as FrID
from
franchise
group by
LastName,
FirstName
) as f
join store s on f.FrID = s.FrID
join pricing p on p.StoreNumber = s.StoreNumber;
The correct output is below.
If I am correct, remove the duplicates entries and change the primary key.
Change Requirements
Okay, you are placing two or more owners in the same table.
Below uses a sub query to combine the owners list into one string. Another way is to have a flag called primary owner. Choose that as the display name.
--
-- Fixed Query - Version 2
--
select
f.OwnersList,
f.FrID,
s.StoreNumber,
s.StoreName,
s.Address,
p.Price1,
p.Price2,
p.Price3
from
-- Compose owners list
(
select
FrID,
(
SELECT FirstName + ' ' + LastName + ';'
FROM franchise as inner1
WHERE inner1.FrID = outer1.FrID
FOR XML PATH('')
) as OwnersList
from franchise as outer1
group by FrID
) as f (FrId, OwnersList)
join store s on f.FrID = s.FrID
join pricing p on p.StoreNumber = s.StoreNumber
Here is the output from the second query.

Distinct over one column with value comparing on another column ICriteria NHibernate

I have table and object called Person. I have problem to create a distinct (over column "lastname") criteria. I want to get only the oldest Person with distinct lastnames.
For example i have (properties: firstname, lastname, age):
John Smith, 52
Jessica Smith, 45
Ann Pit, 21
Brad Pit, 30
Can anybody help me to create criteria which result i get Person object with John Smith and Brad Pit?
Probably the best approach here is to use EXISTS to filter the result set, first a SQL example to get the logic correct:
DECLARE #Person TABLE (
Id INT,
Firstname VARCHAR(20),
Lastname VARCHAR(20),
Age INT
)
INSERT INTO #Person VALUES (1, 'Brad', 'Pitt', 42)
INSERT INTO #Person VALUES (2, 'Angelina', 'Pitt', 45)
INSERT INTO #Person VALUES (3, 'John', 'Smith', 50)
INSERT INTO #Person VALUES (4, 'Jane', 'Smith', 55)
SELECT P.* FROM #Person P
WHERE EXISTS(
SELECT SUB.LastName, MAX(SUB.Age) as Age FROM #Person SUB
GROUP BY SUB.LastName
HAVING SUB.LastName = P.LastName AND MAX(SUB.Age) = P.Age)
This yields the following results which is as expected:
Id Firstname Lastname Age
-------------------------------
2 Angelina Pitt 45
4 Jane Smith 55
Now to convert to nHibernate, this effectively builds the same query as above:
var subQuery = DetachedCriteria.For<Person>("SUB")
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("LastName"), "Lastname")
.Add(Projections.Max("Age"), "Age"))
.Add(Restrictions.EqProperty(Projections.Max("Age"), "P.Age")
.Add(Restrictions.EqProperty("LastName", "P.LastName"));
return session.CreateCriteria<Person>("P")
.Add(Subqueries.Exists(subQuery))
.List<Person>();