我正在寻找两个表,标准是如果users表在分支代码字段中有任何内容,那么SQL查询将只返回它们的分支代码。
但是,如果users表在分支代码框中有NULL,它将返回分支表中的所有分支代码。
以下是我的尝试,我知道不起作用,但应该给我正在使用的表和字段的一些倾向。
SELECT IF(u.BranchCode IS NOT NULL THEN b.BranchCode ELSE u.BranchCode END ) AS BranchCode, b.BranchName, b.BranchAddress1, b.BranchAddress2
FROM users AS u
LEFT JOIN branches AS b ON u.BranchCode = b.BranchCode
WHERE u.Username = '$_SESSION[USERNAME]'
一些表格示例:
用户
UserName | BranchCode
---------|------------------
bob | NULL
sam | AW3456
dave | NULL
alison | NULL
fred | NULL
分行
BranchCode| BranchName |BranchAddress1 |BranchAddress2
----------|-------------|---------------|-------------------
AQ3459 | Northmore |1 Northmore Rd |Northmore Village
AW3456 | Middleton |28 Main Rd |Middleton Stoney
DE5689 | Western |451 Station Rd |Western
FR3278 | Easterly |12 Acacia Dr |Easterly Estate
因此,例如,如果bob是登录的用户,则返回所有BranchCode信息:
BranchCode| BranchName |BranchAddress1 |BranchAddress2
----------|-------------|---------------|-------------------
AQ3459 | Northmore |1 Northmore Rd |Northmore Village
AW3456 | Middleton |28 Main Rd |Middleton Stoney
DE5689 | Western |451 Station Rd |Western
FR3278 | Easterly |12 Acacia Dr |Easterly Estate
如果sam是登录的用户,则只返回他在Branch表中指定的BranchCode信息的查找:
BranchCode| BranchName |BranchAddress1 |BranchAddress2
----------|-------------|---------------|-------------------
AW3456 | Middleton |28 Main Rd |Middleton Stoney
答案 0 :(得分:1)
也许有人更好的SQL会以纯SQL的方式来回答这个问题,但我倾向于保持我的查询相当简单,因为我喜欢在我的编码中遵循KISS规则。我希望他们这样做,因为这个答案并没有100%以你想要的方式回答你的问题。
使用您给我们的SQL,我可以假设您使用PHP进行此查询。此外,从您的查询中可以看出,您之前已经调用过users表。在THAT通话中,将BranchId
列存储在会话中,就像使用用户名变量一样。
假设$_SESSION['branchId']
已设置(即使它可能为NULL)且您的mysqli_connect()
调用存储在名为$con
的变量中,您可以执行以下操作:
$sql = "SELECT * FROM branches";
if($_SESSION['branchId']!==null){
$sql.= " WHERE BranchCode='".mysqli_real_escape_string($con,$_SESSION['branchId'])."'";
}
$result = mysqli_query($con,$sql);
//Fetch rows as usual.
如果您的表已有ID列,请随意忽略下一部分。
现在,我真的不确定为什么你的表的结构是这样的。我知道每个分支在交谈时可能都有一个字母数字的电话号码(例如,如果你打电话给另一个分支,你会说像#34;我是来自AW2011分支的杰克,......")但是{{3}是真实的,并且反击它的最好和最简单的方法之一是对引用变量进行类型转换,以便删除任何额外的输入。但是,这仅对整数类型的引用列有用,因为字符串列仍需要转义。考虑到这一点,您会注意到我在branchId周围使用mysqli_real_escape_string()
,因为我知道它将是一个字符串值。
很多人会推荐像SQL Injection之类的东西,虽然我可能已经为你提供了链接,但它有时会让人很困惑,而且我并不完全是PHP的忠实粉丝#39; PDO连接。 MySQLi扩展还提供了自己的语句准备版本,这些都没有立刻让我感到惊讶。他们看起来都很复杂,我觉得不必要。但如果您需要使用字符串数据,它们绝对是避免SQL注入的最佳方法。
如果您的表格没有更多的参考,我无法确定您的数据实际上是什么样的,但我的逻辑是,如果您有一个user_id列,那么您将无法通过用户名栏。因此,我建议您在任何表上创建的每个记录都有一个ID列。这简化了对SQL注入的防护,因为我可以将mysql_real_escape_string()
语句中的文本缩短为
if()
长度调用。
$sql .= 'WHERE branch_id='.(int)$_SESSION['branchId'];
在大多数情况下,这几乎应该是防范SQL注入所需的全部内容。如果有人要更改你的会话数据(我确信可能,但从未决定尝试),他们试图输入的任何额外文本都将被删除或导致SQL运行不正常。 (不过,请不要引用我的内容。我读过很久以前读过的关于PHP类型转换的变量,所以我可能完全错了。)
如果您不清楚ID列是什么或如何使用它,请随意提出另一个问题,希望有人比我向您解释的更准确。
答案 1 :(得分:1)
只是为了展示一种在纯SQL中执行此操作的方法。
你可以使用INNER JOIN做一个UNION,另一个使用CROSS JOIN(因为在这种情况下两个表之间没有关系)
select b.BranchCode, b.BranchName, b.BranchAddress1, b.BranchAddress2
from users u
inner join branches b on u.BranchCode = b.BranchCode
where u.UserName = '$_SESSION'
and u.BranchCode is not null -- just for clarity, it's not neeeded
union
select b.BranchCode, b.BranchName, b.BranchAddress1, b.BranchAddress2
from branches b
CROSS JOIN users u
where u.UserName = '$_SESSION[USERNAME]'
and u.BranchCode is null
请参阅SqlFiddle(我添加了UserName以更好地了解两个用户正在发生的事情,一个用NULL BranchCode,一个用有效的BranchCode)