我对SQL非常陌生,我刚开始在家里的SQL Management Studio 2014中创建自己的数据库。所以我还在学习基础知识。 该数据库名为FitnessClub(我组建的一家虚构公司)。
在该数据库中,我有三个表:Pupils,Sports和PupilsSports(我认为你称之为联结表?)请假设我已经在所有表中整理了PK和FK正确。
我决定增加20个学生和10个体育项目。我已经连续分配了前10名学生的10名学生,这意味着剩下的10名学生没有被分配运动。
在我的PupilsSports表中,我有PupilID(PK)和SportID(PK)都与其他两个表中的相应列有关,这就是我用这样简单的方式添加了10个Piess和10个体育项目的地方:
+-----+-------+
| P.ID | S.ID |
+-----+-------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 | 9 |
| 10 | 10 |
+-----+-------+
我想创建一个SQL查询,我可以运行以查找尚未分配给某项运动的学生列表?这可能吗?
谢谢
答案 0 :(得分:1)
外部联接和空值的过滤器应该可以解决问题。像这样:
SELECT
*
FROM
Pupils
LEFT OUTER JOIN PupilsSports
ON Pupils.ID = PupilsSports.PupilID
WHERE
PupilsSports.SportID IS NULL
基本上,外连接将为您提供连接两个表的完整超集,将值保留为NULL
,其中未找到匹配的记录。因此,对NULL
子句中的WHERE
值进行过滤会减少结果集,使其仅包含未找到匹配连接记录的记录。
或者也许是一种子查询方法:
SELECT
*
FROM
Pupils
WHERE
ID NOT IN (SELECT PupilID FROM PupilsSports)
我想,有很多种方法可以完成这项任务。可能有趣的学习经历是在SQL Management Studio中检查每种方法的查询执行计划,看看它们之间的区别以及可能出现的任何潜在瓶颈。
答案 1 :(得分:0)
许多方法可以让那只猫皮肤......这是一个相对容易理解的方法:
SELECT * FROM Pupils WHERE PupilID NOT IN (SELECT PupilID FROM PupilsSports)
答案 2 :(得分:0)
为了不为您简单地编写此查询,我会尝试指出您需要的内容。首先,您需要将package com.example.user.testing;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
public class MainActivity extends AppCompatActivity {
CheckBox dontShowAgain;
public static final String PREFS_NAME = "MyPrefsFile1";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this);
LayoutInflater adbInflater = LayoutInflater.from(MainActivity.this);
View eulaLayout = adbInflater.inflate(R.layout.checkbox, null);
dontShowAgain = (CheckBox) eulaLayout.findViewById(R.id.skip);
adb.setView(eulaLayout);
adb.setTitle("Attention");
adb.setMessage("Your message here");
adb.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("skipMessage", dontShowAgain.isChecked());
editor.commit();
dialog.cancel();
}
});
adb.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
Boolean skipMessage = settings.getBoolean("skipMessage", false);
if (skipMessage.equals(false)) {
adb.show();
}
}
这两个表放在一起。 JOIN
将从左侧表中获取所有行,并且仅匹配右侧表中的行。
如果您列出了所有具有相应体育项目的学生(或LEFT JOIN
没有体育项目),那么您可以使用NULL
语句进行过滤。请记住,要指出WHERE
值,您必须使用NULL
之类的内容,而不是使用等于运算符WHERE Sports IS NULL
。