Don't want to fetch single column (name) - mysql

def fetchProposalByStudio(studioId: Int): List[ProposalDetails] = {
ConnectionPoolManager.getDB(config = appConfig).localTx { implicit session: DBSession =>
logger.info("Querying proposal table to fetch all the proposals")
SQL("""SELECT [except name] p.id, id, proposal_title, challenge, possible_solution, explanation,
| submission_date, status, submitted_by, remark
| FROM proposal p inner join knolder k on k.id = p.knolder_id
| where k.studio_id =? order by p.id desc""".stripMargin)
.bind(studioId)
.map(rs =>
ProposalDetails(
rs.int("id"),
rs.int("id"),
rs.string("proposal_title"),
rs.string("challenge"),
rs.string("possible_solution"),
rs.string("explanation"),
rs.string("submission_date"),
Some(ProposalStatus.withName(rs.string("status"))),
rs.string("submitted_by"),
rs.string("remark"),
**rs.string("name")**
)
)
.list().apply()
}
}
I don't want to fetch this column name in my query but without involving this in the query i am getting this error due to using case class.
13:28:24.446 [default-akka.actor.default-dispatcher-8] INFO c.k.l.b.ProposalImpl - Something went wrong while fetching the proposals. Exception message: ERROR: syntax error at or near "["
Position: 8

Smells of a syntax problem...
Perhaps:
SELECT [except name] -- should be
SELECT `except name` -- in mysql

If you don't want a particular column in an SQL resultset, you simply don't mention it in the SELECT.
There is no notion of SELECT * EXCEPT FirstName FROM person - if Person has FirstName, LastName, Age, Address and you don't want FirstName, you don't put it in the select list:
SELECT LastName, Age, Address FROM Person
^^^^^^^
no FirstName mentioned here
Mention every column you do want, do not mention any column you don't want.
If the complaint is "but there are 527 columns and I want all except one" - you can do something like:
SELECT CONCAT(column_name, ',') FROM information_schema.columns WHERE table_name = 'Person' and column_name <> 'FirstName'
which produces a resultset like:
LastName,
Age,
Address,
... 523 other columns
And you can then copy that resultset and paste it into your code, and it already has commas on the end..
If you want the columns all on one line, use GROUP_CONCAT or use a decent text editor to replace \r\n with nothing. If you want to surround the column name in backticks, put it into the CONCAT.. The ultimate point here is that you're a software developer: you can write code that writes code, then you can copy the output, which is valid code, and paste it into some other code somewhere else

Related

SELECT statement showing difference in between columns of two tables

I have 2 tables.
T_before and T_after, these two have the same table structure(datatypes, field name all the same).
T_before is the data right now in the moment.
T_after the the data that is used to check for differences.
I want to write a SELECT statement to extract which field is changed when comparing those two tables.
eg. For the same ID, T_before.name != T_after.name so in the 'changedField' column(which is created from the SELECT statement) is concatenated with string 'name'
Right now I wrote this.
SELECT CASE(WHEN T_before.name != T_after.name THEN 'name, ' ELSE '' END CASE) AS f1,
CASE(WHEN T_before.address != T_after.address THEN 'address, ' ELSE '' END CASE) AS f2,
CONCAT(f1,f2) AS changedField
FROM T_before INNER JOIN T_after ON (T_before.id = T_after.id);
Now, I have about 150 fields to check. It is quite a lot field to create with this SELECT statement(Or is it not alot?). I there a better way to do this?
EDIT:
Result at the moment:
f1 |f2 |changedField
name, |address, |name, address,
The desired result:
changedField
name, address,
As mentioned, I have about 150 fields to check, so that is quite a number of field the sql statement I wrote will return

where clause in COUNT function and joining two queries

I have a table that I am trying to count the number of course passed, and also list the modules passed as well.
The first problem I am having is what to put in the where variable, so that its not specific to a customer(I can use the query below for a particular customer and a particular course)but I will like a generic query where the result will be distinct in terms of user and course like the one below
SELECT FirstName
,LastName
,CourseTitle
,Noofmodules
,count(Coursecompleted) AS modulescompleted
FROM EStudentsprogress
WHERE Coursecompleted = '1'
AND EmailAddress = 'scascsc#e.co.uk'
AND CourseTitle = 'Microsoft MOS 2010 EXCEL'
GROUP BY FirstName
,LastName
,CourseTitle
,Noofmodules
How can I make it list the result as above, whereby I don't specify the email address or course title(trying to get the result for all the clients )
Also I have a query that list the courses that is passed by the customer, I will like the column with the list of courses passed be added to the result above, but as a column for each course.
SELECT FirstName
,LastName
,CourseTitle
,EmailAddress
,CourseModule AS coursepassed
FROM EStudentsprogress
WHERE coursecompleted = 1
Cheers
Can you not just add the email address and course title fields to the select fields and the GROUP BY clause.
Also you can use GROUP_CONCAT to bring back a field containing all the course modules.
Something like this:-
SELECT FirstName,
LastName,
CourseTitle,
Noofmodules,
EmailAddress,
CourseTitlecount,
COUNT(Coursecompleted) as modulescompleted,
GROUP_CONCAT(CourseModule) as modulescompletednames
FROM EStudentsprogress
WHERE Coursecompleted = '1'
GROUP BY FirstName, LastName, CourseTitle, Noofmodules, EmailAddress, CourseTitlecount ;

get the label through the foreign key

These are my table.
My tables are
User table
id Name Sex
1 bob 1
2 taro 1
3 can 2
Sex table
id label
1 male
2 female
User.sex is foreign key of Sex.id
What I want to get is like this below
Name Sex
bob male
taro female
can female
$query = $em->createQuery(
SELECT a,id,a.sex
FROM UserBundle:User a)
it says
[Semantical Error] line 0, col 97 near 'sex': Error: Invalid PathExpression. Must be a StateFieldPathExpression
I guess Identity could help this problem.
So I tried such as
$query = $em->createQuery(
SELECT a,id,IDENTITY(a.sex) AS sex
FROM UserBundle:User a)
$user = $query->getResult();
$user[0]['sex'] //
it shows '1'(id) but I wan to show the label name
please give some hint.
thanks alot
The canonical way to accomplish this task in SQL is to use a subquery. Something to the effect of:
Select u.name s.label
From user u, sex s
where s.ID in (Select sex
from u
where u.id = 1);
will get you any one user record with a labeled sex.
so you'll need to modify your prepared statement in such a way as to run a subquery.
For multiple records in the result set, you may consider phrasing your SQL statement using an inner join.
Select u.name s.label
from user u inner join sex s
on u.sex = s.id;
will get you a matched set of each user's name and the label for their gender.
It looks like you're using something like a scripting language prepared statement functionality (is that php?), so make sure to read over your language's syntax on properly setting up a prepared statement to avoid an injection attack from a malicious user.

Why is this ActiveRecord Query NOT ambiguous?

With Rails 3, I am using the following kind of code to query a MySQL database:
MyData.joins('JOIN (SELECT id, name FROM sellers) AS Q
ON seller_id = Q.id').
select('*').
joins('JOIN (SELECT id, name FROM users) AS T
ON user_id = T.id').
select("*").each do |record|
#..........
Then, a bit further down, I try to access a "name" with this code: (note that both sellers and users have a name column).
str = record.name
This line is giving me a "user name" instead of a "seller name", but shouldn't it give nothing? Since I joined multiple tables with a name column, shouldn't I be get an error like "column 'name' is ambiguous"? Why isn't this happening?
And by the way, the code behaves the same way whether I include that first "select('*')" line or not.
Thank you.
Firstly, there's no reason to call select twice - only the last call will actually be used. Secondly, you should not be using select("*"), because the SQL database (and Rails) will not rename the ambiguous columns for you. Instead, use explicit naming for the extra columns that you need:
MyData.joins('JOIN (SELECT..) AS Q ON ...', 'JOIN (SELECT...) AS T ON ...').
select('my_datas.*, T.name as t_name, Q.name as q_name').
each do |record|
# do something
end
Because of this, there's no reason to make a subquery in your JOIN statements:
MyData.joins('JOIN sellers AS Q ON ...', 'JOIN users AS T ON ...').
And finally, you should already have belongs_to associations set up for seller and user. That would mean that you can just do this:
MyData.joins(:seller, :user).
select("my_datas.*, sellers.name as seller_name, users.name as user_name").
each do |record|
# do something
end
Now you can call record.seller_name and record.user_name without any ambiguity.

MySQL COALESCE alternative for selecting both result sets for an insert, not either / or?

so I'm having a problem with this following query.. So, the query is only selecting either the comment.author_id OR the stream.author_id for insertion, whereas I need it to select both where it meets the where conditions so it inserts notifications for both a stream items author id, and the author id for all comments associated with the target stream id. All help is appreciated
INSERT INTO notification
(text, type, target_id, sender_id, recipient_id, data, timestamp, is_unread)
SELECT DISTINCT '$text', 'comment', '$id', '$senderId',
COALESCE(comment.author_id, stream.author_id),
'$dataArray','$timestamp', '1'
FROM stream
LEFT JOIN comment ON comment.target_id = stream.id
WHERE (comment.target_id = '$id' OR stream.id = '$id')
AND comment.author_id != '$senderId'"
AND stream.author_id != '$senderId'
I agree with gbn. If for some reason you have to concatenate them you can use the concat() or concat_ws() function.
concat(col1,col2,...):
select concat('a','b','c');
Returns:
abc
concat_ws(separater,col1,col2,...):
select concat_ws(',','a','b','c');
Returns:
a,b,c
You need to watch out for special situations with casting types. Look at this section on String Functions in the manual.